<!DOCTYPE html>
<html lang="zh-CN">
    <head>
    <meta charset="utf-8">

    

    <!-- 渲染优化 -->
    <meta name="renderer" content="webkit">
    <meta name="force-rendering" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <meta name="HandheldFriendly" content="True" >
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

    <!--icon-->

    
        <link rel="shortcut icon" href="https://s1.imgpp.com/2022/01/28/owl.png">
    
    
    
    
    


    <!-- meta -->


<title>Spring MVC | 猫头鹰的BLOG</title>


    <meta name="keywords" content="Spring MVC, 猫头鹰的博客">




    <!-- OpenGraph -->
 
    <meta name="description" content="Spring MVCSpring MVC 是目前主流的实现 MVC 设计模式的企业级开发框架，Spring 框架的一个子模块，无需整合，开发起来更加便捷。 什么是 MVC 设计模式？将应用程序分为 Controller、Model、View 三层，Controller 接收客户端请求，调用 Model 生成业务数据，传递给 View。 Spring MVC 就是对这套流程的封装，屏蔽了很多底层代码">
<meta property="og:type" content="article">
<meta property="og:title" content="Spring MVC">
<meta property="og:url" content="http://example.com/2022/04/09/SpringMVC/index.html">
<meta property="og:site_name" content="猫头鹰的BLOG">
<meta property="og:description" content="Spring MVCSpring MVC 是目前主流的实现 MVC 设计模式的企业级开发框架，Spring 框架的一个子模块，无需整合，开发起来更加便捷。 什么是 MVC 设计模式？将应用程序分为 Controller、Model、View 三层，Controller 接收客户端请求，调用 Model 生成业务数据，传递给 View。 Spring MVC 就是对这套流程的封装，屏蔽了很多底层代码">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://images.pexels.com/photos/8086373/pexels-photo-8086373.jpeg?cs=srgb&dl=pexels-ron-lach-8086373.jpg&fm=jpg">
<meta property="article:published_time" content="2022-04-09T02:00:20.000Z">
<meta property="article:modified_time" content="2022-04-09T11:25:54.389Z">
<meta property="article:author" content="张程">
<meta property="article:tag" content="Spring MVC">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://images.pexels.com/photos/8086373/pexels-photo-8086373.jpeg?cs=srgb&dl=pexels-ron-lach-8086373.jpg&fm=jpg">


    
<link rel="stylesheet" href="/css/style/main.css">
 

    
    
    
        <link rel="stylesheet" id="hl-default-theme" href="https://cdn.jsdelivr.net/npm/highlight.js@10.1.2/styles/arduino-light.min.css" media="none" >
        
            <link rel="stylesheet" id="hl-dark-theme" href="https://cdn.jsdelivr.net/npm/highlight.js@10.1.2/styles/obsidian.min.css" media="none">
        
    

    

    
    
<link rel="stylesheet" href="/css/style/dark.css">

    
<script src="/js/darkmode.js"></script>



     
    <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
 

    <!-- custom head -->

<meta name="generator" content="Hexo 6.0.0"></head>

    <body>
        <div id="app">
            <header class="header">
    <div class="header__left">
        <a href="/" class="button">
            <span class="logo__text">猫头鹰</span>
        </a>
    </div>
    <div class="header__right">
        
            <div class="navbar__menus">
                
                    <a href="/" class="navbar-menu button">首页</a>
                
                    <a href="/tags/" class="navbar-menu button">标签</a>
                
                    <a href="/categories/" class="navbar-menu button">分类</a>
                
                    <a href="/archives/" class="navbar-menu button">归档</a>
                
            </div>
        
        
        
    <a href="/search/" id="btn-search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="24" height="24" fill="currentColor" stroke="currentColor" stroke-width="32"><path d="M192 448c0-141.152 114.848-256 256-256s256 114.848 256 256-114.848 256-256 256-256-114.848-256-256z m710.624 409.376l-206.88-206.88A318.784 318.784 0 0 0 768 448c0-176.736-143.264-320-320-320S128 271.264 128 448s143.264 320 320 320a318.784 318.784 0 0 0 202.496-72.256l206.88 206.88 45.248-45.248z"></path></svg>
    </a>


        
        
    <a href="javaScript:void(0);" id="btn-toggle-dark">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
    </a>


        
            <a class="dropdown-icon button" id="btn-dropdown" tabindex="0"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width='24' height='24' fill="none" stroke="currentColor" stroke-width="0.7" stroke-linecap="round" stroke-linejoin="round"><path fill="currentColor" d="M3.314,4.8h13.372c0.41,0,0.743-0.333,0.743-0.743c0-0.41-0.333-0.743-0.743-0.743H3.314c-0.41,0-0.743,0.333-0.743,0.743C2.571,4.467,2.904,4.8,3.314,4.8z M16.686,15.2H3.314c-0.41,0-0.743,0.333-0.743,0.743s0.333,0.743,0.743,0.743h13.372c0.41,0,0.743-0.333,0.743-0.743S17.096,15.2,16.686,15.2z M16.686,9.257H3.314c-0.41,0-0.743,0.333-0.743,0.743s0.333,0.743,0.743,0.743h13.372c0.41,0,0.743-0.333,0.743-0.743S17.096,9.257,16.686,9.257z"></path></svg></a>
            <div class="dropdown-menus" id="dropdown-menus">
                
                    <a href="/" class="dropdown-menu button">首页</a>
                
                    <a href="/tags/" class="dropdown-menu button">标签</a>
                
                    <a href="/categories/" class="dropdown-menu button">分类</a>
                
                    <a href="/archives/" class="dropdown-menu button">归档</a>
                
            </div>
        
    </div>
</header>


            <main class="main">
    

<div class="post-title">
    <h1 class="post-title__text">
        Spring MVC
    </h1>
    <div class="post-title__meta">
        <a href="/archives/2022/04/" class="post-meta__date button">2022-04-09</a>
        
    <span class="separate-dot"></span><a href="/categories/Spring-MVC/" class="button">Spring MVC</a>

 
        
    
     
    <span id="busuanzi_container_page_pv" hidden>
        <span class="separate-dot"></span>
        <span></span>
        <span id="busuanzi_value_page_pv"></span>
        <span>次观看</span>
    </span>



 

 
    </div>
</div>



<article class="post content-card">
    <div class="post__header">
    
        <div class="post-thumbnail lazy" data-bg="https://images.pexels.com/photos/8086373/pexels-photo-8086373.jpeg?cs=srgb&amp;dl=pexels-ron-lach-8086373.jpg&amp;fm=jpg"></div>
    
</div>
    <div class="post__content">
        <h3 id="Spring-MVC"><a href="#Spring-MVC" class="headerlink" title="Spring MVC"></a>Spring MVC</h3><p>Spring MVC 是目前主流的实现 MVC 设计模式的企业级开发框架，Spring 框架的一个子模块，无需整合，开发起来更加便捷。</p>
<h4 id="什么是-MVC-设计模式？"><a href="#什么是-MVC-设计模式？" class="headerlink" title="什么是 MVC 设计模式？"></a>什么是 MVC 设计模式？</h4><p>将应用程序分为 Controller、Model、View 三层，Controller 接收客户端请求，调用 Model 生成业务数据，传递给 View。</p>
<p>Spring MVC 就是对这套流程的封装，屏蔽了很多底层代码，开放出接口，让开发者可以更加轻松、便捷地完成基于 MVC 模式的 Web 开发。</p>
<h4 id="Spring-MVC-的核心组件"><a href="#Spring-MVC-的核心组件" class="headerlink" title="Spring MVC 的核心组件"></a>Spring MVC 的核心组件</h4><ul>
<li>DispatcherServlet：前置控制器，是整个流程控制的核心，控制其他组件的执行，进行统一调度，降低组件之间的耦合性，相当于总指挥。</li>
<li>Handler：处理器，完成具体的业务逻辑，相当于 Servlet 或 Action。</li>
<li>HandlerMapping：DispatcherServlet 接收到请求之后，通过 HandlerMapping 将不同的请求映射到不同的 Handler。</li>
<li>HandlerInterceptor：处理器拦截器，是一个接口，如果需要完成一些拦截处理，可以实现该接口。</li>
<li>HandlerExecutionChain：处理器执行链，包括两部分内容：Handler 和 HandlerInterceptor（系统会有一个默认的 HandlerInterceptor，如果需要额外设置拦截，可以添加拦截器）。</li>
<li>HandlerAdapter：处理器适配器，Handler 执行业务方法之前，需要进行一系列的操作，包括表单数据的验证、数据类型的转换、将表单数据封装到 JavaBean 等，这些操作都是由 HandlerApater 来完成，开发者只需将注意力集中业务逻辑的处理上，DispatcherServlet 通过 HandlerAdapter 执行不同的 Handler。</li>
<li>ModelAndView：装载了模型数据和视图信息，作为 Handler 的处理结果，返回给 DispatcherServlet。</li>
<li>ViewResolver：视图解析器，DispatcheServlet 通过它将逻辑视图解析为物理视图，最终将渲染结果响应给客户端。</li>
</ul>
<h4 id="Spring-MVC-的工作流程"><a href="#Spring-MVC-的工作流程" class="headerlink" title="Spring MVC 的工作流程"></a>Spring MVC 的工作流程</h4><ul>
<li>客户端请求被 DisptacherServlet 接收。</li>
<li>根据 HandlerMapping 映射到 Handler。</li>
<li>生成 Handler 和 HandlerInterceptor。</li>
<li>Handler 和 HandlerInterceptor 以 HandlerExecutionChain 的形式一并返回给 DisptacherServlet。</li>
<li>DispatcherServlet 通过 HandlerAdapter 调用 Handler 的方法完成业务逻辑处理。</li>
<li>Handler 返回一个 ModelAndView 给 DispatcherServlet。</li>
<li>DispatcherServlet 将获取的 ModelAndView 对象传给 ViewResolver 视图解析器，将逻辑视图解析为物理视图 View。</li>
<li>ViewResovler 返回一个 View 给 DispatcherServlet。</li>
<li>DispatcherServlet 根据 View 进行视图渲染（将模型数据 Model 填充到视图 View 中）。</li>
<li>DispatcherServlet 将渲染后的结果响应给客户端。</li>
</ul>
<p>![image-20190313111136254](/Users/southwind/Library/Application Support/typora-user-images/image-20190313111136254.png)</p>
<p>Spring MVC 流程非常复杂，实际开发中很简单，因为大部分的组件不需要开发者创建、管理，只需要通过配置文件的方式完成配置即可，真正需要开发者进行处理的只有 Handler 、View。</p>
<h4 id="如何使用？"><a href="#如何使用？" class="headerlink" title="如何使用？"></a>如何使用？</h4><ul>
<li>创建 Maven 工程，pom.xml</li>
</ul>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span>
 
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-webmvc<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>5.0.11.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
 
<span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span></code></pre>

<ul>
<li>在 web.xml 中配置 DispatcherServlet。</li>
</ul>
<pre><code class="hljs xml"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">web-app</span> <span class="hljs-meta-keyword">PUBLIC</span></span>
<span class="hljs-meta"> <span class="hljs-meta-string">&quot;-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN&quot;</span></span>
<span class="hljs-meta"> <span class="hljs-meta-string">&quot;http://java.sun.com/dtd/web-app_2_3.dtd&quot;</span> &gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">web-app</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">display-name</span>&gt;</span>Archetype Created Web Application<span class="hljs-tag">&lt;/<span class="hljs-name">display-name</span>&gt;</span>
   
  <span class="hljs-tag">&lt;<span class="hljs-name">servlet</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">servlet-name</span>&gt;</span>dispatcherServlet<span class="hljs-tag">&lt;/<span class="hljs-name">servlet-name</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">servlet-class</span>&gt;</span>org.springframework.web.servlet.DispatcherServlet<span class="hljs-tag">&lt;/<span class="hljs-name">servlet-class</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">init-param</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">param-name</span>&gt;</span>contextConfigLocation<span class="hljs-tag">&lt;/<span class="hljs-name">param-name</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">param-value</span>&gt;</span>classpath:springmvc.xml<span class="hljs-tag">&lt;/<span class="hljs-name">param-value</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">init-param</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">servlet</span>&gt;</span>
   
  <span class="hljs-tag">&lt;<span class="hljs-name">servlet-mapping</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">servlet-name</span>&gt;</span>dispatcherServlet<span class="hljs-tag">&lt;/<span class="hljs-name">servlet-name</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">url-pattern</span>&gt;</span>/<span class="hljs-tag">&lt;/<span class="hljs-name">url-pattern</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">servlet-mapping</span>&gt;</span>
   
<span class="hljs-tag">&lt;/<span class="hljs-name">web-app</span>&gt;</span></code></pre>

<ul>
<li>springmvc.xml</li>
</ul>
<pre><code class="hljs xml"><span class="hljs-meta">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">beans</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/beans&quot;</span></span>
<span class="hljs-tag">       <span class="hljs-attr">xmlns:xsi</span>=<span class="hljs-string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span>
<span class="hljs-tag">       <span class="hljs-attr">xmlns:context</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/context&quot;</span></span>
<span class="hljs-tag">       <span class="hljs-attr">xmlns:mvc</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/mvc&quot;</span></span>
<span class="hljs-tag">       <span class="hljs-attr">xsi:schemaLocation</span>=<span class="hljs-string">&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd</span></span>
<span class="hljs-string"><span class="hljs-tag">       http://www.springframework.org/schema/mvc</span></span>
<span class="hljs-string"><span class="hljs-tag">       http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd&quot;</span>&gt;</span>
 
    <span class="hljs-comment">&lt;!-- 自动扫描 --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">context:component-scan</span> <span class="hljs-attr">base-package</span>=<span class="hljs-string">&quot;com.southwind&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">context:component-scan</span>&gt;</span>
 
    <span class="hljs-comment">&lt;!-- 配置视图解析器 --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;prefix&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;/&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;suffix&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;.jsp&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
<span class="hljs-tag">&lt;/<span class="hljs-name">beans</span>&gt;</span></code></pre>

<ul>
<li>创建 Handler</li>
</ul>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.controller;
 
<span class="hljs-keyword">import</span> org.springframework.stereotype.Controller;
<span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RequestMapping;
 
<span class="hljs-meta">@Controller</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HelloHandler</span> </span>&#123;
 
    <span class="hljs-meta">@RequestMapping(&quot;/index&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">index</span><span class="hljs-params">()</span></span>&#123;
        System.out.println(<span class="hljs-string">&quot;执行了index...&quot;</span>);
        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;index&quot;</span>;
    &#125;
&#125;</code></pre>

<h3 id="Spring-MVC-注解"><a href="#Spring-MVC-注解" class="headerlink" title="Spring MVC 注解"></a>Spring MVC 注解</h3><ul>
<li>@RequestMapping </li>
</ul>
<p>Spring MVC 通过 @RequestMapping 注解将 URL 请求与业务方法进行映射，在 Handler 的类定义处以及方法定义处都可以添加 @RequestMapping ，在类定义处添加，相当于客户端多了一层访问路径。</p>
<ul>
<li>@Controller</li>
</ul>
<p>@Controller 在类定义处添加，将该类交个 IoC 容器来管理（结合 springmvc.xml 的自动扫描配置使用），同时使其成为一个控制器，可以接收客户端请求。</p>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.controller;
 
<span class="hljs-keyword">import</span> org.springframework.stereotype.Controller;
<span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RequestMapping;
 
<span class="hljs-meta">@Controller</span>
<span class="hljs-meta">@RequestMapping(&quot;/hello&quot;)</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HelloHandler</span> </span>&#123;
 
    <span class="hljs-meta">@RequestMapping(&quot;/index&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">index</span><span class="hljs-params">()</span></span>&#123;
        System.out.println(<span class="hljs-string">&quot;执行了index...&quot;</span>);
        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;index&quot;</span>;
    &#125;
&#125;</code></pre>

<ul>
<li>@RequestMapping 相关参数</li>
</ul>
<p>1、value：指定 URL 请求的实际地址，是 @RequestMapping 的默认值。</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/index&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">index</span><span class="hljs-params">()</span></span>&#123;
    System.out.println(<span class="hljs-string">&quot;执行了index...&quot;</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;index&quot;</span>;
&#125;</code></pre>

<p>等于</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(value=&quot;/index&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">index</span><span class="hljs-params">()</span></span>&#123;
    System.out.println(<span class="hljs-string">&quot;执行了index...&quot;</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;index&quot;</span>;
&#125;</code></pre>

<p>2、method：指定请求的 method 类型，GET、POST、PUT、DELET。</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(value = &quot;/index&quot;,method = RequestMethod.GET)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">index</span><span class="hljs-params">()</span></span>&#123;
    System.out.println(<span class="hljs-string">&quot;执行了index...&quot;</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;index&quot;</span>;
&#125;</code></pre>

<p>上述代码表示 index 方法只能接收 GET 请求。</p>
<p>3、params：指定请求中必须包含某些参数，否则无法调用该方法。</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(value = &quot;/index&quot;,method = RequestMethod.GET,params = &#123;&quot;name&quot;,&quot;id=10&quot;&#125;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">index</span><span class="hljs-params">()</span></span>&#123;
    System.out.println(<span class="hljs-string">&quot;执行了index...&quot;</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;index&quot;</span>;
&#125;</code></pre>

<p>上述代码表示请求中必须包含 name 和 id 两个参数，同时 id 的值必须是 10。</p>
<p>关于参数绑定，在形参列表中通过添加 @RequestParam 注解完成 HTTP 请求参数与业务方法形参的映射。</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(value = &quot;/index&quot;,method = RequestMethod.GET,params = &#123;&quot;name&quot;,&quot;id=10&quot;&#125;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">index</span><span class="hljs-params">(<span class="hljs-meta">@RequestParam(&quot;name&quot;)</span> String str,<span class="hljs-meta">@RequestParam(&quot;id&quot;)</span> <span class="hljs-keyword">int</span> age)</span></span>&#123;
    System.out.println(str);
    System.out.println(age);
    System.out.println(<span class="hljs-string">&quot;执行了index...&quot;</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;index&quot;</span>;
&#125;</code></pre>

<p>上述代码表示将请求的参数 name 和 id 分别赋给了形参 str 和 age ，同时自动完成了数据类型转换，将 “10” 转为了 int 类型的 10，再赋给 age，这些工作都是由 HandlerAdapter 来完成的。</p>
<p>Spring MVC 也支持 RESTful 风格的 URL。</p>
<p>传统类型：<a target="_blank" rel="noopener" href="http://localhost:8080/hello/index?name=zhangsan&amp;id=10">http://localhost:8080/hello/index?name=zhangsan&amp;id=10</a></p>
<p>REST：<a target="_blank" rel="noopener" href="http://localhost:8080/hello/index/zhangsan/10">http://localhost:8080/hello/index/zhangsan/10</a></p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/rest/&#123;name&#125;/&#123;id&#125;&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">rest</span><span class="hljs-params">(<span class="hljs-meta">@PathVariable(&quot;name&quot;)</span> String name,<span class="hljs-meta">@PathVariable(&quot;id&quot;)</span> <span class="hljs-keyword">int</span> id)</span></span>&#123;
    System.out.println(name);
    System.out.println(id);
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;index&quot;</span>;
&#125;</code></pre>

<p>通过 @PathVariable 注解完成请求参数与形参的映射。</p>
<ul>
<li>映射 Cookie</li>
</ul>
<p>Spring MVC 通过映射可以直接在业务方法中获取 Cookie 的值。</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/cookie&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">cookie</span><span class="hljs-params">(<span class="hljs-meta">@CookieValue(value = &quot;JSESSIONID&quot;)</span> String sessionId)</span></span>&#123;
    System.out.println(sessionId);
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;index&quot;</span>;
&#125;</code></pre>

<ul>
<li>使用 JavaBean 绑定参数</li>
</ul>
<p>Spring MVC 会根据请求参数名和 JavaBean 属性名进行自动匹配，自动为对象填充属性值，同时支持及联属性。</p>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.entity;
 
<span class="hljs-keyword">import</span> lombok.Data;
 
<span class="hljs-meta">@Data</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Address</span> </span>&#123;
    <span class="hljs-keyword">private</span> String value;
&#125;</code></pre>

<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.entity;
 
<span class="hljs-keyword">import</span> lombok.Data;
 
<span class="hljs-meta">@Data</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>&#123;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">long</span> id;
    <span class="hljs-keyword">private</span> String name;
    <span class="hljs-keyword">private</span> Address address;
&#125;</code></pre>

<pre><code class="hljs jsp">&lt;%--
  Created by IntelliJ IDEA.
  User: southwind
  Date: <span class="hljs-number">2019</span>-<span class="hljs-number">03</span>-<span class="hljs-number">13</span>
  Time: <span class="hljs-number">15</span>:<span class="hljs-number">33</span>
  To change <span class="hljs-keyword">this</span> template use File | Settings | File Templates.
--%&gt;
&lt;%@ page contentType=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span> language=<span class="hljs-string">&quot;java&quot;</span> %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form action=<span class="hljs-string">&quot;/hello/save&quot;</span> method=<span class="hljs-string">&quot;post&quot;</span>&gt;
        用户id：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;id&quot;</span>/&gt;&lt;br/&gt;
        用户名：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;name&quot;</span>/&gt;&lt;br/&gt;
        用户地址：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;address.value&quot;</span>/&gt;&lt;br/&gt;
        &lt;input type=<span class="hljs-string">&quot;submit&quot;</span> value=<span class="hljs-string">&quot;注册&quot;</span>/&gt;
    &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>

<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(value = &quot;/save&quot;,method = RequestMethod.POST)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">save</span><span class="hljs-params">(User user)</span></span>&#123;
    System.out.println(user);
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;index&quot;</span>;
&#125;</code></pre>

<p>如果出现中文乱码问题，只需在 web.xml 添加 Spring MVC 自带的过滤器即可。</p>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">filter</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">filter-name</span>&gt;</span>encodingFilter<span class="hljs-tag">&lt;/<span class="hljs-name">filter-name</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">filter-class</span>&gt;</span>org.springframework.web.filter.CharacterEncodingFilter<span class="hljs-tag">&lt;/<span class="hljs-name">filter-class</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">init-param</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">param-name</span>&gt;</span>encoding<span class="hljs-tag">&lt;/<span class="hljs-name">param-name</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">param-value</span>&gt;</span>UTF-8<span class="hljs-tag">&lt;/<span class="hljs-name">param-value</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">init-param</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">filter</span>&gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">filter-mapping</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">filter-name</span>&gt;</span>encodingFilter<span class="hljs-tag">&lt;/<span class="hljs-name">filter-name</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">url-pattern</span>&gt;</span>/*<span class="hljs-tag">&lt;/<span class="hljs-name">url-pattern</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">filter-mapping</span>&gt;</span></code></pre>

<ul>
<li>JSP 页面的转发和重定向：</li>
</ul>
<p>Spring MVC 默认是以转发的形式响应 JSP。</p>
<p>1、转发</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/forward&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">forward</span><span class="hljs-params">()</span></span>&#123;
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;forward:/index.jsp&quot;</span>;
    <span class="hljs-comment">//        return &quot;index&quot;;</span>
&#125;</code></pre>

<p>2、重定向</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/redirect&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">redirect</span><span class="hljs-params">()</span></span>&#123;
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;redirect:/index.jsp&quot;</span>;
&#125;</code></pre>

<h3 id="Spring-MVC-数据绑定"><a href="#Spring-MVC-数据绑定" class="headerlink" title="Spring MVC 数据绑定"></a>Spring MVC 数据绑定</h3><p>数据绑定：在后端的业务方法中直接获取客户端 HTTP 请求中的参数，将请求参数映射到业务方法的形参中，Spring MVC 中数据绑定的工作是由 HandlerAdapter 来完成的。</p>
<ul>
<li>基本数据类型</li>
</ul>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/baseType&quot;)</span>
<span class="hljs-meta">@ResponseBody</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">baseType</span><span class="hljs-params">(<span class="hljs-keyword">int</span> id)</span></span>&#123;
    <span class="hljs-keyword">return</span> id+<span class="hljs-string">&quot;&quot;</span>;
&#125;</code></pre>

<p>@ResponseBody 表示 Spring MVC 会直接将业务方法的返回值响应给客户端，如果不加 @ResponseBody 注解，Spring MVC 会将业务方法的放回值传递给 DispatcherServlet，再由 DisptacherServlet 调用 ViewResolver 对返回值进行解析，映射到一个 JSP 资源。</p>
<ul>
<li>包装类</li>
</ul>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/packageType&quot;)</span>
<span class="hljs-meta">@ResponseBody</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">packageType</span><span class="hljs-params">(<span class="hljs-meta">@RequestParam(value = &quot;num&quot;,required = false,defaultValue = &quot;0&quot;)</span> Integer id)</span></span>&#123;
    <span class="hljs-keyword">return</span> id+<span class="hljs-string">&quot;&quot;</span>;
&#125;</code></pre>

<p>包装类可以接收 null，当 HTTP 请求没有参数时，使用包装类定义形参的数据类型，程序不会抛出异常。</p>
<p>@RequestParam</p>
<p>value = “num”：将 HTTP 请求中名为 num 的参数赋给形参 id。</p>
<p>requried：设置 num 是否为必填项，true 表示必填，false 表示非必填，可省略。</p>
<p>defaultValue = “0”：如果 HTTP 请求中没有 num 参数，默认值为0.</p>
<ul>
<li>数组</li>
</ul>
<pre><code class="hljs java"><span class="hljs-meta">@RestController</span>
<span class="hljs-meta">@RequestMapping(&quot;/data&quot;)</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DataBindHandler</span> </span>&#123;
    <span class="hljs-meta">@RequestMapping(&quot;/array&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">array</span><span class="hljs-params">(String[] name)</span></span>&#123;
        String str = Arrays.toString(name);
        <span class="hljs-keyword">return</span> str;
    &#125;
&#125;</code></pre>

<p>@RestController 表示该控制器会直接将业务方法的返回值响应给客户端，不进行视图解析。</p>
<p>@Controller 表示该控制器的每一个业务方法的返回值都会交给视图解析器进行解析，如果只需要将数据响应给客户端，而不需要进行视图解析，则需要在对应的业务方法定义处添加 @ResponseBody。</p>
<pre><code class="hljs java"><span class="hljs-meta">@RestController</span>
<span class="hljs-meta">@RequestMapping(&quot;/data&quot;)</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DataBindHandler</span> </span>&#123;
    <span class="hljs-meta">@RequestMapping(&quot;/array&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">array</span><span class="hljs-params">(String[] name)</span></span>&#123;
        String str = Arrays.toString(name);
        <span class="hljs-keyword">return</span> str;
    &#125;
&#125;</code></pre>

<p>等同于</p>
<pre><code class="hljs java"><span class="hljs-meta">@Controller</span>
<span class="hljs-meta">@RequestMapping(&quot;/data&quot;)</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DataBindHandler</span> </span>&#123;
    <span class="hljs-meta">@RequestMapping(&quot;/array&quot;)</span>
    <span class="hljs-meta">@ResponseBody</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">array</span><span class="hljs-params">(String[] name)</span></span>&#123;
        String str = Arrays.toString(name);
        <span class="hljs-keyword">return</span> str;
    &#125;
&#125;</code></pre>

<ul>
<li>List</li>
</ul>
<p>Spring MVC 不支持 List 类型的直接转换，需要对 List 集合进行包装。</p>
<p>集合封装类</p>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.entity;
 
<span class="hljs-keyword">import</span> lombok.Data;
 
<span class="hljs-keyword">import</span> java.util.List;
 
<span class="hljs-meta">@Data</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserList</span> </span>&#123;
    <span class="hljs-keyword">private</span> List&lt;User&gt; users;
&#125;</code></pre>

<p>JSP</p>
<pre><code class="hljs jsp">&lt;%--
  Created by IntelliJ IDEA.
  User: southwind
  Date: <span class="hljs-number">2019</span>-<span class="hljs-number">03</span>-<span class="hljs-number">14</span>
  Time: 09:<span class="hljs-number">12</span>
  To change <span class="hljs-keyword">this</span> template use File | Settings | File Templates.
--%&gt;
&lt;%@ page contentType=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span> language=<span class="hljs-string">&quot;java&quot;</span> %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form action=<span class="hljs-string">&quot;/data/list&quot;</span> method=<span class="hljs-string">&quot;post&quot;</span>&gt;
        用户<span class="hljs-number">1</span>编号：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;users[0].id&quot;</span>/&gt;&lt;br/&gt;
        用户<span class="hljs-number">1</span>名称：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;users[0].name&quot;</span>/&gt;&lt;br/&gt;
        用户<span class="hljs-number">2</span>编号：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;users[1].id&quot;</span>/&gt;&lt;br/&gt;
        用户<span class="hljs-number">2</span>名称：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;users[1].name&quot;</span>/&gt;&lt;br/&gt;
        用户<span class="hljs-number">3</span>编号：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;users[2].id&quot;</span>/&gt;&lt;br/&gt;
        用户<span class="hljs-number">3</span>名称：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;users[2].name&quot;</span>/&gt;&lt;br/&gt;
        &lt;input type=<span class="hljs-string">&quot;submit&quot;</span> value=<span class="hljs-string">&quot;提交&quot;</span>/&gt;
    &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>

<p>业务方法</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/list&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">list</span><span class="hljs-params">(UserList userList)</span></span>&#123;
    StringBuffer str = <span class="hljs-keyword">new</span> StringBuffer();
    <span class="hljs-keyword">for</span>(User user:userList.getUsers())&#123;
        str.append(user);
    &#125;
    <span class="hljs-keyword">return</span> str.toString();
&#125;</code></pre>

<p>处理 @ResponseBody 中文乱码，在 springmvc.xml 中配置消息转换器。</p>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">mvc:annotation-driven</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- 消息转换器 --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">mvc:message-converters</span> <span class="hljs-attr">register-defaults</span>=<span class="hljs-string">&quot;true&quot;</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;org.springframework.http.converter.StringHttpMessageConverter&quot;</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;supportedMediaTypes&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">mvc:message-converters</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">mvc:annotation-driven</span>&gt;</span></code></pre>

<ul>
<li>Map</li>
</ul>
<p>自定义封装类</p>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.entity;
 
<span class="hljs-keyword">import</span> lombok.Data;
 
<span class="hljs-keyword">import</span> java.util.Map;
 
<span class="hljs-meta">@Data</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserMap</span> </span>&#123;
    <span class="hljs-keyword">private</span> Map&lt;String,User&gt; users;
&#125;</code></pre>

<p>业务方法</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/map&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">map</span><span class="hljs-params">(UserMap userMap)</span></span>&#123;
    StringBuffer str = <span class="hljs-keyword">new</span> StringBuffer();
    <span class="hljs-keyword">for</span>(String key:userMap.getUsers().keySet())&#123;
        User user = userMap.getUsers().get(key);
        str.append(user);
    &#125;
    <span class="hljs-keyword">return</span> str.toString();
&#125;</code></pre>

<p>JSP</p>
<pre><code class="hljs jsp">&lt;%--
  Created by IntelliJ IDEA.
  User: southwind
  Date: <span class="hljs-number">2019</span>-<span class="hljs-number">03</span>-<span class="hljs-number">14</span>
  Time: 09:<span class="hljs-number">12</span>
  To change <span class="hljs-keyword">this</span> template use File | Settings | File Templates.
--%&gt;
&lt;%@ page contentType=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span> language=<span class="hljs-string">&quot;java&quot;</span> %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form action=<span class="hljs-string">&quot;/data/map&quot;</span> method=<span class="hljs-string">&quot;post&quot;</span>&gt;
        用户<span class="hljs-number">1</span>编号：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;users[&#x27;a&#x27;].id&quot;</span>/&gt;&lt;br/&gt;
        用户<span class="hljs-number">1</span>名称：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;users[&#x27;a&#x27;].name&quot;</span>/&gt;&lt;br/&gt;
        用户<span class="hljs-number">2</span>编号：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;users[&#x27;b&#x27;].id&quot;</span>/&gt;&lt;br/&gt;
        用户<span class="hljs-number">2</span>名称：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;users[&#x27;b&#x27;].name&quot;</span>/&gt;&lt;br/&gt;
        用户<span class="hljs-number">3</span>编号：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;users[&#x27;c&#x27;].id&quot;</span>/&gt;&lt;br/&gt;
        用户<span class="hljs-number">3</span>名称：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;users[&#x27;c&#x27;].name&quot;</span>/&gt;&lt;br/&gt;
        &lt;input type=<span class="hljs-string">&quot;submit&quot;</span> value=<span class="hljs-string">&quot;提交&quot;</span>/&gt;
    &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>

<ul>
<li>JSON</li>
</ul>
<p>客户端发生 JSON 格式的数据，直接通过 Spring MVC 绑定到业务方法的形参中。</p>
<p>处理 Spring MVC 无法加载静态资源，在 web.xml 中添加配置即可。</p>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">servlet-mapping</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">servlet-name</span>&gt;</span>default<span class="hljs-tag">&lt;/<span class="hljs-name">servlet-name</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">url-pattern</span>&gt;</span>*.js<span class="hljs-tag">&lt;/<span class="hljs-name">url-pattern</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">servlet-mapping</span>&gt;</span></code></pre>

<p>JSP</p>
<pre><code class="hljs jsp">&lt;%--
  Created by IntelliJ IDEA.
  User: southwind
  Date: <span class="hljs-number">2019</span>-<span class="hljs-number">03</span>-<span class="hljs-number">14</span>
  Time: <span class="hljs-number">10</span>:<span class="hljs-number">35</span>
  To change <span class="hljs-keyword">this</span> template use File | Settings | File Templates.
--%&gt;
&lt;%@ page contentType=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span> language=<span class="hljs-string">&quot;java&quot;</span> %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Title&lt;/title&gt;
    &lt;script type=<span class="hljs-string">&quot;text/javascript&quot;</span> src=<span class="hljs-string">&quot;js/jquery-3.3.1.min.js&quot;</span>&gt;&lt;/script&gt;
    &lt;script type=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;
        $(function()&#123;
           <span class="hljs-keyword">var</span> user = &#123;
               <span class="hljs-string">&quot;id&quot;</span>:<span class="hljs-number">1</span>,
               <span class="hljs-string">&quot;name&quot;</span>:<span class="hljs-string">&quot;张三&quot;</span>
           &#125;;
           $.ajax(&#123;
               url:<span class="hljs-string">&quot;/data/json&quot;</span>,
               data:JSON.stringify(user),
               type:<span class="hljs-string">&quot;POST&quot;</span>,
               contentType:<span class="hljs-string">&quot;application/json;charset=UTF-8&quot;</span>,
               dataType:<span class="hljs-string">&quot;JSON&quot;</span>,
               success:function(data)&#123;
                   alter(data.id+<span class="hljs-string">&quot;---&quot;</span>+data.name);
               &#125;
           &#125;)
        &#125;);
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
 
&lt;/body&gt;
&lt;/html&gt;</code></pre>

<p>业务方法</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/json&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> User <span class="hljs-title">json</span><span class="hljs-params">(<span class="hljs-meta">@RequestBody</span> User user)</span></span>&#123;
    System.out.println(user);
    user.setId(<span class="hljs-number">6</span>);
    user.setName(<span class="hljs-string">&quot;张六&quot;</span>);
    <span class="hljs-keyword">return</span> user;
&#125;</code></pre>

<p>Spring MVC 中的 JSON 和 JavaBean 的转换需要借助于 fastjson，pom.xml 引入相关依赖。</p>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.alibaba<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>fastjson<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.2.32<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></code></pre>

<p>springmvc.xml 添加 fastjson 配置。</p>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">mvc:annotation-driven</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- 消息转换器 --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">mvc:message-converters</span> <span class="hljs-attr">register-defaults</span>=<span class="hljs-string">&quot;true&quot;</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;org.springframework.http.converter.StringHttpMessageConverter&quot;</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;supportedMediaTypes&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- 配置fastjson --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">mvc:message-converters</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">mvc:annotation-driven</span>&gt;</span></code></pre>

<h3 id="Spring-MVC-模型数据解析"><a href="#Spring-MVC-模型数据解析" class="headerlink" title="Spring MVC 模型数据解析"></a>Spring MVC 模型数据解析</h3><p>JSP 四大作用域对应的内置对象：pageContext、request、session、application。</p>
<p>模型数据的绑定是由 ViewResolver 来完成的，实际开发中，我们需要先添加模型数据，再交给 ViewResolver 来绑定。</p>
<p>Spring MVC 提供了以下几种方式添加模型数据：</p>
<ul>
<li>Map</li>
<li>Model</li>
<li>ModelAndView</li>
<li>@SessionAttribute</li>
<li>@ModelAttribute</li>
</ul>
<blockquote>
<p>将模式数据绑定到 request 对象。</p>
</blockquote>
<p>1、Map</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/map&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">map</span><span class="hljs-params">(Map&lt;String,User&gt; map)</span></span>&#123;
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    map.put(<span class="hljs-string">&quot;user&quot;</span>,user);
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;view&quot;</span>;
&#125;</code></pre>

<p>JSP</p>
<pre><code class="hljs jsp">&lt;%--
  Created by IntelliJ IDEA.
  User: southwind
  Date: <span class="hljs-number">2019</span>-<span class="hljs-number">03</span>-<span class="hljs-number">14</span>
  Time: <span class="hljs-number">11</span>:<span class="hljs-number">36</span>
  To change <span class="hljs-keyword">this</span> template use File | Settings | File Templates.
--%&gt;
&lt;%@ page contentType=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span> language=<span class="hljs-string">&quot;java&quot;</span> %&gt;
&lt;%@ page isELIgnored=<span class="hljs-string">&quot;false&quot;</span> %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    $&#123;requestScope.user&#125;
&lt;/body&gt;
&lt;/html&gt;</code></pre>

<p>2、Model</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/model&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">model</span><span class="hljs-params">(Model model)</span></span>&#123;
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    model.addAttribute(<span class="hljs-string">&quot;user&quot;</span>,user);
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;view&quot;</span>;
&#125;</code></pre>

<p>3、ModelAndView</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/modelAndView&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> ModelAndView <span class="hljs-title">modelAndView</span><span class="hljs-params">()</span></span>&#123;
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    ModelAndView modelAndView = <span class="hljs-keyword">new</span> ModelAndView();
    modelAndView.addObject(<span class="hljs-string">&quot;user&quot;</span>,user);
    modelAndView.setViewName(<span class="hljs-string">&quot;view&quot;</span>);
    <span class="hljs-keyword">return</span> modelAndView;
&#125;
 
<span class="hljs-meta">@RequestMapping(&quot;/modelAndView2&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> ModelAndView <span class="hljs-title">modelAndView2</span><span class="hljs-params">()</span></span>&#123;
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    ModelAndView modelAndView = <span class="hljs-keyword">new</span> ModelAndView();
    modelAndView.addObject(<span class="hljs-string">&quot;user&quot;</span>,user);
    View view = <span class="hljs-keyword">new</span> InternalResourceView(<span class="hljs-string">&quot;/view.jsp&quot;</span>);
    modelAndView.setView(view);
    <span class="hljs-keyword">return</span> modelAndView;
&#125;
 
<span class="hljs-meta">@RequestMapping(&quot;/modelAndView3&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> ModelAndView <span class="hljs-title">modelAndView3</span><span class="hljs-params">()</span></span>&#123;
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    ModelAndView modelAndView = <span class="hljs-keyword">new</span> ModelAndView(<span class="hljs-string">&quot;view&quot;</span>);
    modelAndView.addObject(<span class="hljs-string">&quot;user&quot;</span>,user);
    <span class="hljs-keyword">return</span> modelAndView;
&#125;
 
<span class="hljs-meta">@RequestMapping(&quot;/modelAndView4&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> ModelAndView <span class="hljs-title">modelAndView4</span><span class="hljs-params">()</span></span>&#123;
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    View view = <span class="hljs-keyword">new</span> InternalResourceView(<span class="hljs-string">&quot;/view.jsp&quot;</span>);
    ModelAndView modelAndView = <span class="hljs-keyword">new</span> ModelAndView(view);
    modelAndView.addObject(<span class="hljs-string">&quot;user&quot;</span>,user);
    <span class="hljs-keyword">return</span> modelAndView;
&#125;
 
<span class="hljs-meta">@RequestMapping(&quot;/modelAndView5&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> ModelAndView <span class="hljs-title">modelAndView5</span><span class="hljs-params">()</span></span>&#123;
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    Map&lt;String,User&gt; map = <span class="hljs-keyword">new</span> HashMap&lt;&gt;();
    map.put(<span class="hljs-string">&quot;user&quot;</span>,user);
    ModelAndView modelAndView = <span class="hljs-keyword">new</span> ModelAndView(<span class="hljs-string">&quot;view&quot;</span>,map);
    <span class="hljs-keyword">return</span> modelAndView;
&#125;
 
<span class="hljs-meta">@RequestMapping(&quot;/modelAndView6&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> ModelAndView <span class="hljs-title">modelAndView6</span><span class="hljs-params">()</span></span>&#123;
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    Map&lt;String,User&gt; map = <span class="hljs-keyword">new</span> HashMap&lt;&gt;();
    map.put(<span class="hljs-string">&quot;user&quot;</span>,user);
    View view = <span class="hljs-keyword">new</span> InternalResourceView(<span class="hljs-string">&quot;/view.jsp&quot;</span>);
    ModelAndView modelAndView = <span class="hljs-keyword">new</span> ModelAndView(view,map);
    <span class="hljs-keyword">return</span> modelAndView;
&#125;
 
<span class="hljs-meta">@RequestMapping(&quot;/modelAndView7&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> ModelAndView <span class="hljs-title">modelAndView7</span><span class="hljs-params">()</span></span>&#123;
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    ModelAndView modelAndView = <span class="hljs-keyword">new</span> ModelAndView(<span class="hljs-string">&quot;view&quot;</span>,<span class="hljs-string">&quot;user&quot;</span>,user);
    <span class="hljs-keyword">return</span> modelAndView;
&#125;
 
<span class="hljs-meta">@RequestMapping(&quot;/modelAndView8&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> ModelAndView <span class="hljs-title">modelAndView8</span><span class="hljs-params">()</span></span>&#123;
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    View view = <span class="hljs-keyword">new</span> InternalResourceView(<span class="hljs-string">&quot;/view.jsp&quot;</span>);
    ModelAndView modelAndView = <span class="hljs-keyword">new</span> ModelAndView(view,<span class="hljs-string">&quot;user&quot;</span>,user);
    <span class="hljs-keyword">return</span> modelAndView;
&#125;</code></pre>

<p>4、HttpServletRequest</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/request&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">request</span><span class="hljs-params">(HttpServletRequest request)</span></span>&#123;
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    request.setAttribute(<span class="hljs-string">&quot;user&quot;</span>,user);
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;view&quot;</span>;
&#125;</code></pre>

<p>5、@ModelAttribute</p>
<ul>
<li>定义一个方法，该方法专门用来返回要填充到模型数据中的对象。</li>
</ul>
<pre><code class="hljs java"><span class="hljs-meta">@ModelAttribute</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> User <span class="hljs-title">getUser</span><span class="hljs-params">()</span></span>&#123;
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    <span class="hljs-keyword">return</span> user;
&#125;</code></pre>

<pre><code class="hljs java"><span class="hljs-meta">@ModelAttribute</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">getUser</span><span class="hljs-params">(Map&lt;String,User&gt; map)</span></span>&#123;
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    map.put(<span class="hljs-string">&quot;user&quot;</span>,user);
&#125;</code></pre>

<pre><code class="hljs java"><span class="hljs-meta">@ModelAttribute</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">getUser</span><span class="hljs-params">(Model model)</span></span>&#123;
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    model.addAttribute(<span class="hljs-string">&quot;user&quot;</span>,user);
&#125;</code></pre>

<ul>
<li>业务方法中无需再处理模型数据，只需返回视图即可。</li>
</ul>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/modelAttribute&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">modelAttribute</span><span class="hljs-params">()</span></span>&#123;
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;view&quot;</span>;
&#125;</code></pre>

<blockquote>
<p>将模型数据绑定到 session 对象</p>
</blockquote>
<p>1、直接使用原生的 Servlet API。</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/session&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">session</span><span class="hljs-params">(HttpServletRequest request)</span></span>&#123;
    HttpSession session = request.getSession();
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    session.setAttribute(<span class="hljs-string">&quot;user&quot;</span>,user);
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;view&quot;</span>;
&#125;
 
<span class="hljs-meta">@RequestMapping(&quot;/session2&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">session2</span><span class="hljs-params">(HttpSession session)</span></span>&#123;
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    session.setAttribute(<span class="hljs-string">&quot;user&quot;</span>,user);
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;view&quot;</span>;
&#125;</code></pre>

<p>2、@SessionAttribute</p>
<pre><code class="hljs java"><span class="hljs-meta">@SessionAttributes(value = &#123;&quot;user&quot;,&quot;address&quot;&#125;)</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ViewHandler</span> </span>&#123;
&#125;</code></pre>

<p>对于 ViewHandler 中的所有业务方法，只要向 request 中添加了 key = “user”、key = “address” 的对象时，Spring MVC 会自动将该数据添加到 session 中，保存 key 不变。</p>
<pre><code class="hljs java"><span class="hljs-meta">@SessionAttributes(types = &#123;User.class,Address.class&#125;)</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ViewHandler</span> </span>&#123;
&#125;</code></pre>

<p>对于 ViewHandler 中的所有业务方法，只要向 request 中添加了数据类型是 User 、Address 的对象时，Spring MVC 会自动将该数据添加到 session 中，保存 key 不变。</p>
<blockquote>
<p>将模型数据绑定到 application 对象</p>
</blockquote>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/application&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">application</span><span class="hljs-params">(HttpServletRequest request)</span></span>&#123;
    ServletContext application = request.getServletContext();
    User user = <span class="hljs-keyword">new</span> User();
    user.setId(<span class="hljs-number">1L</span>);
    user.setName(<span class="hljs-string">&quot;张三&quot;</span>);
    application.setAttribute(<span class="hljs-string">&quot;user&quot;</span>,user);
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;view&quot;</span>;
&#125;</code></pre>

<h3 id="Spring-MVC-自定义数据转换器"><a href="#Spring-MVC-自定义数据转换器" class="headerlink" title="Spring MVC 自定义数据转换器"></a>Spring MVC 自定义数据转换器</h3><p>数据转换器是指将客户端 HTTP 请求中的参数转换为业务方法中定义的形参，自定义表示开发者可以自主设计转换的方式，HandlerApdter 已经提供了通用的转换，String 转 int，String 转 double，表单数据的封装等，但是在特殊的业务场景下，HandlerAdapter 无法进行转换，就需要开发者自定义转换器。</p>
<p>客户端输入 String 类型的数据 “2019-03-03”，自定义转换器将该数据转为 Date 类型的对象。</p>
<ul>
<li>创建 DateConverter 转换器，实现 Conveter 接口。</li>
</ul>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.converter;
 
<span class="hljs-keyword">import</span> org.springframework.core.convert.converter.Converter;
 
<span class="hljs-keyword">import</span> java.text.ParseException;
<span class="hljs-keyword">import</span> java.text.SimpleDateFormat;
<span class="hljs-keyword">import</span> java.util.Date;
 
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DateConverter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Converter</span>&lt;<span class="hljs-title">String</span>, <span class="hljs-title">Date</span>&gt; </span>&#123;
 
    <span class="hljs-keyword">private</span> String pattern;
 
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">DateConverter</span><span class="hljs-params">(String pattern)</span></span>&#123;
        <span class="hljs-keyword">this</span>.pattern = pattern;
    &#125;
 
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Date <span class="hljs-title">convert</span><span class="hljs-params">(String s)</span> </span>&#123;
        SimpleDateFormat simpleDateFormat = <span class="hljs-keyword">new</span> SimpleDateFormat(<span class="hljs-keyword">this</span>.pattern);
        Date date = <span class="hljs-keyword">null</span>;
        <span class="hljs-keyword">try</span> &#123;
            date = simpleDateFormat.parse(s);
        &#125; <span class="hljs-keyword">catch</span> (ParseException e) &#123;
            e.printStackTrace();
        &#125;
        <span class="hljs-keyword">return</span> date;
    &#125;
&#125;</code></pre>

<ul>
<li>springmvc.xml 配置转换器。</li>
</ul>
<pre><code class="hljs xml"><span class="hljs-comment">&lt;!-- 配置自定义转换器 --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;conversionService&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;org.springframework.context.support.ConversionServiceFactoryBean&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;converters&quot;</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">list</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.converter.DateConverter&quot;</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">constructor-arg</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;java.lang.String&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;yyyy-MM-dd&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">constructor-arg</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">list</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">mvc:annotation-driven</span> <span class="hljs-attr">conversion-service</span>=<span class="hljs-string">&quot;conversionService&quot;</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- 消息转换器 --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">mvc:message-converters</span> <span class="hljs-attr">register-defaults</span>=<span class="hljs-string">&quot;true&quot;</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;org.springframework.http.converter.StringHttpMessageConverter&quot;</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;supportedMediaTypes&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- 配置fastjson --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">mvc:message-converters</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">mvc:annotation-driven</span>&gt;</span></code></pre>

<ul>
<li>JSP</li>
</ul>
<pre><code class="hljs jsp">&lt;%--
  Created by IntelliJ IDEA.
  User: southwind
  Date: <span class="hljs-number">2019</span>-<span class="hljs-number">03</span>-<span class="hljs-number">14</span>
  Time: <span class="hljs-number">14</span>:<span class="hljs-number">47</span>
  To change <span class="hljs-keyword">this</span> template use File | Settings | File Templates.
--%&gt;
&lt;%@ page contentType=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span> language=<span class="hljs-string">&quot;java&quot;</span> %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form action=<span class="hljs-string">&quot;/converter/date&quot;</span> method=<span class="hljs-string">&quot;post&quot;</span>&gt;
        请输入日期:&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;date&quot;</span>/&gt;(yyyy-MM-dd)&lt;br/&gt;
        &lt;input type=<span class="hljs-string">&quot;submit&quot;</span> value=<span class="hljs-string">&quot;提交&quot;</span>/&gt;
    &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>

<ul>
<li>Handler</li>
</ul>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.controller;
 
<span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RequestMapping;
<span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RestController;
 
<span class="hljs-keyword">import</span> java.util.Date;
 
<span class="hljs-meta">@RestController</span>
<span class="hljs-meta">@RequestMapping(&quot;/converter&quot;)</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ConverterHandler</span> </span>&#123;
 
    <span class="hljs-meta">@RequestMapping(&quot;/date&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">date</span><span class="hljs-params">(Date date)</span></span>&#123;
        <span class="hljs-keyword">return</span> date.toString();
    &#125;
&#125;</code></pre>

<p>String 转 Student</p>
<p>StudentConverter</p>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.converter;
 
<span class="hljs-keyword">import</span> com.southwind.entity.Student;
<span class="hljs-keyword">import</span> org.springframework.core.convert.converter.Converter;
 
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StudentConverter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Converter</span>&lt;<span class="hljs-title">String</span>, <span class="hljs-title">Student</span>&gt; </span>&#123;
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Student <span class="hljs-title">convert</span><span class="hljs-params">(String s)</span> </span>&#123;
        String[] args = s.split(<span class="hljs-string">&quot;-&quot;</span>);
        Student student = <span class="hljs-keyword">new</span> Student();
        student.setId(Long.parseLong(args[<span class="hljs-number">0</span>]));
        student.setName(args[<span class="hljs-number">1</span>]);
        student.setAge(Integer.parseInt(args[<span class="hljs-number">2</span>]));
        <span class="hljs-keyword">return</span> student;
    &#125;
&#125;</code></pre>

<p>springmvc.xml</p>
<pre><code class="hljs xml"><span class="hljs-comment">&lt;!-- 配置自定义转换器 --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;conversionService&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;org.springframework.context.support.ConversionServiceFactoryBean&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;converters&quot;</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">list</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.converter.DateConverter&quot;</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">constructor-arg</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;java.lang.String&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;yyyy-MM-dd&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">constructor-arg</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.converter.StudentConverter&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">list</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">mvc:annotation-driven</span> <span class="hljs-attr">conversion-service</span>=<span class="hljs-string">&quot;conversionService&quot;</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- 消息转换器 --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">mvc:message-converters</span> <span class="hljs-attr">register-defaults</span>=<span class="hljs-string">&quot;true&quot;</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;org.springframework.http.converter.StringHttpMessageConverter&quot;</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;supportedMediaTypes&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">property</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- 配置fastjson --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">mvc:message-converters</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">mvc:annotation-driven</span>&gt;</span></code></pre>

<p>JSP</p>
<pre><code class="hljs jsp">&lt;%--
  Created by IntelliJ IDEA.
  User: southwind
  Date: <span class="hljs-number">2019</span>-<span class="hljs-number">03</span>-<span class="hljs-number">14</span>
  Time: <span class="hljs-number">15</span>:<span class="hljs-number">23</span>
  To change <span class="hljs-keyword">this</span> template use File | Settings | File Templates.
--%&gt;
&lt;%@ page contentType=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span> language=<span class="hljs-string">&quot;java&quot;</span> %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form action=<span class="hljs-string">&quot;/converter/student&quot;</span> method=<span class="hljs-string">&quot;post&quot;</span>&gt;
        请输入学生信息：&lt;input type=<span class="hljs-string">&quot;text&quot;</span> name=<span class="hljs-string">&quot;student&quot;</span>/&gt;(id-name-age)&lt;br/&gt;
        &lt;input type=<span class="hljs-string">&quot;submit&quot;</span> value=<span class="hljs-string">&quot;提交&quot;</span>/&gt;
    &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>

<p>Handler</p>
<pre><code class="hljs java"><span class="hljs-meta">@RequestMapping(&quot;/student&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">student</span><span class="hljs-params">(Student student)</span></span>&#123;
    <span class="hljs-keyword">return</span> student.toString();
&#125;</code></pre>

<h3 id="Spring-MVC-REST"><a href="#Spring-MVC-REST" class="headerlink" title="Spring MVC REST"></a>Spring MVC REST</h3><p>REST：Representational State Transfer，资源表现层状态转换，是目前比较主流的一种互联网软件架构，它结构清晰、标准规范、易于理解、便于扩展。</p>
<ul>
<li>资源（Resource）</li>
</ul>
<p>网络上的一个实体，或者说网络中存在的一个具体信息，一段文本、一张图片、一首歌曲、一段视频等等，总之就是一个具体的存在。可以用一个 URI（统一资源定位符）指向它，每个资源都有对应的一个特定的 URI，要获取该资源时，只需要访问对应的 URI 即可。</p>
<ul>
<li>表现层（Representation）</li>
</ul>
<p>资源具体呈现出来的形式，比如文本可以用 txt 格式表示，也可以用 HTML、XML、JSON等格式来表示。</p>
<ul>
<li>状态转换（State Transfer）</li>
</ul>
<p>客户端如果希望操作服务器中的某个资源，就需要通过某种方式让服务端发生状态转换，而这种转换是建立在表现层之上的，所有叫做”表现层状态转换”。</p>
<h4 id="特点"><a href="#特点" class="headerlink" title="特点"></a>特点</h4><ul>
<li>URL 更加简洁。</li>
<li>有利于不同系统之间的资源共享，只需要遵守一定的规范，不需要进行其他配置即可实现资源共享。</li>
</ul>
<h4 id="如何使用"><a href="#如何使用" class="headerlink" title="如何使用"></a>如何使用</h4><p>REST 具体操作就是 HTTP 协议中四个表示操作方式的动词分别对应 CRUD 基本操作。</p>
<p>GET 用来表示获取资源。</p>
<p>POST 用来表示新建资源。</p>
<p>PUT 用来表示修改资源。</p>
<p>DELETE 用来表示删除资源。</p>
<p>Handler</p>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.controller;
 
<span class="hljs-keyword">import</span> com.southwind.entity.Student;
<span class="hljs-keyword">import</span> com.southwind.entity.User;
<span class="hljs-keyword">import</span> com.southwind.repository.StudentRepository;
<span class="hljs-keyword">import</span> org.springframework.beans.factory.annotation.Autowired;
<span class="hljs-keyword">import</span> org.springframework.stereotype.Repository;
<span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.*;
 
<span class="hljs-keyword">import</span> javax.servlet.http.HttpServletResponse;
<span class="hljs-keyword">import</span> java.util.Collection;
 
<span class="hljs-meta">@RestController</span>
<span class="hljs-meta">@RequestMapping(&quot;/rest&quot;)</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RESTHandeler</span> </span>&#123;
 
    <span class="hljs-meta">@Autowired</span>
    <span class="hljs-keyword">private</span> StudentRepository studentRepository;
 
    <span class="hljs-meta">@GetMapping(&quot;/findAll&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Collection&lt;Student&gt; <span class="hljs-title">findAll</span><span class="hljs-params">(HttpServletResponse response)</span></span>&#123;
        response.setContentType(<span class="hljs-string">&quot;text/json;charset=UTF-8&quot;</span>);
        <span class="hljs-keyword">return</span> studentRepository.findAll();
    &#125;
 
    <span class="hljs-meta">@GetMapping(&quot;/findById/&#123;id&#125;&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Student <span class="hljs-title">findById</span><span class="hljs-params">(<span class="hljs-meta">@PathVariable(&quot;id&quot;)</span> <span class="hljs-keyword">long</span> id)</span></span>&#123;
        <span class="hljs-keyword">return</span> studentRepository.findById(id);
    &#125;
 
    <span class="hljs-meta">@PostMapping(&quot;/save&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">save</span><span class="hljs-params">(<span class="hljs-meta">@RequestBody</span> Student student)</span></span>&#123;
        studentRepository.saveOrUpdate(student);
    &#125;
 
    <span class="hljs-meta">@PutMapping(&quot;/update&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">update</span><span class="hljs-params">(<span class="hljs-meta">@RequestBody</span> Student student)</span></span>&#123;
        studentRepository.saveOrUpdate(student);
    &#125;
 
    <span class="hljs-meta">@DeleteMapping(&quot;/deleteById/&#123;id&#125;&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">deleteById</span><span class="hljs-params">(<span class="hljs-meta">@PathVariable(&quot;id&quot;)</span> <span class="hljs-keyword">long</span> id)</span></span>&#123;
        studentRepository.deleteById(id);
    &#125;
 
&#125;</code></pre>

<p>StudentRepository</p>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.repository;
 
<span class="hljs-keyword">import</span> com.southwind.entity.Student;
 
<span class="hljs-keyword">import</span> java.util.Collection;
 
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">StudentRepository</span> </span>&#123;
    <span class="hljs-function"><span class="hljs-keyword">public</span> Collection&lt;Student&gt; <span class="hljs-title">findAll</span><span class="hljs-params">()</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">public</span> Student <span class="hljs-title">findById</span><span class="hljs-params">(<span class="hljs-keyword">long</span> id)</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">saveOrUpdate</span><span class="hljs-params">(Student student)</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">deleteById</span><span class="hljs-params">(<span class="hljs-keyword">long</span> id)</span></span>;
&#125;</code></pre>

<p>StudentRepositoryImpl</p>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.repository.impl;
 
<span class="hljs-keyword">import</span> com.southwind.entity.Student;
<span class="hljs-keyword">import</span> com.southwind.repository.StudentRepository;
<span class="hljs-keyword">import</span> org.springframework.stereotype.Repository;
 
<span class="hljs-keyword">import</span> java.util.Collection;
<span class="hljs-keyword">import</span> java.util.HashMap;
<span class="hljs-keyword">import</span> java.util.Map;
 
<span class="hljs-meta">@Repository</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StudentRepositoryImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">StudentRepository</span> </span>&#123;
 
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> Map&lt;Long,Student&gt; studentMap;
 
    <span class="hljs-keyword">static</span>&#123;
        studentMap = <span class="hljs-keyword">new</span> HashMap&lt;&gt;();
        studentMap.put(<span class="hljs-number">1L</span>,<span class="hljs-keyword">new</span> Student(<span class="hljs-number">1L</span>,<span class="hljs-string">&quot;张三&quot;</span>,<span class="hljs-number">22</span>));
        studentMap.put(<span class="hljs-number">2L</span>,<span class="hljs-keyword">new</span> Student(<span class="hljs-number">2L</span>,<span class="hljs-string">&quot;李四&quot;</span>,<span class="hljs-number">23</span>));
        studentMap.put(<span class="hljs-number">3L</span>,<span class="hljs-keyword">new</span> Student(<span class="hljs-number">3L</span>,<span class="hljs-string">&quot;王五&quot;</span>,<span class="hljs-number">24</span>));
    &#125;
 
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Collection&lt;Student&gt; <span class="hljs-title">findAll</span><span class="hljs-params">()</span> </span>&#123;
        <span class="hljs-keyword">return</span> studentMap.values();
    &#125;
 
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Student <span class="hljs-title">findById</span><span class="hljs-params">(<span class="hljs-keyword">long</span> id)</span> </span>&#123;
        <span class="hljs-keyword">return</span> studentMap.get(id);
    &#125;
 
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">saveOrUpdate</span><span class="hljs-params">(Student student)</span> </span>&#123;
        studentMap.put(student.getId(),student);
    &#125;
 
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">deleteById</span><span class="hljs-params">(<span class="hljs-keyword">long</span> id)</span> </span>&#123;
        studentMap.remove(id);
    &#125;
&#125;</code></pre>

<h3 id="Spring-MVC-文件上传下载"><a href="#Spring-MVC-文件上传下载" class="headerlink" title="Spring MVC 文件上传下载"></a>Spring MVC 文件上传下载</h3><blockquote>
<p>单文件上传</p>
</blockquote>
<p>底层是使用 Apache fileupload 组件完成上传，Spring MVC 对这种方式进行了封装。</p>
<ul>
<li>pom.xml</li>
</ul>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>commons-io<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>commons-io<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.5<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>commons-fileupload<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>commons-fileupload<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.3.3<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></code></pre>

<ul>
<li>JSP</li>
</ul>
<pre><code class="hljs jsp">&lt;%--
  Created by IntelliJ IDEA.
  User: southwind
  Date: <span class="hljs-number">2019</span>-<span class="hljs-number">03</span>-<span class="hljs-number">15</span>
  Time: 09:09
  To change <span class="hljs-keyword">this</span> template use File | Settings | File Templates.
--%&gt;
&lt;%@ page contentType=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span> language=<span class="hljs-string">&quot;java&quot;</span> %&gt;
&lt;%@ page isELIgnored=<span class="hljs-string">&quot;false&quot;</span> %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form action=<span class="hljs-string">&quot;/file/upload&quot;</span> method=<span class="hljs-string">&quot;post&quot;</span> enctype=<span class="hljs-string">&quot;multipart/form-data&quot;</span>&gt;
        &lt;input type=<span class="hljs-string">&quot;file&quot;</span> name=<span class="hljs-string">&quot;img&quot;</span>/&gt;
        &lt;input type=<span class="hljs-string">&quot;submit&quot;</span> value=<span class="hljs-string">&quot;上传&quot;</span>/&gt;
    &lt;/form&gt;
    &lt;img src=<span class="hljs-string">&quot;$&#123;path&#125;&quot;</span>&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>

<p>1、input 的 type 设置为 file。</p>
<p>2、form 的 method 设置为 post（get 请求只能将文件名传给服务器）</p>
<p>3、from 的 enctype 设置为 multipart-form-data（如果不设置只能将文件名传给服务器）</p>
<ul>
<li>Handler</li>
</ul>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.controller;
 
<span class="hljs-keyword">import</span> org.springframework.stereotype.Controller;
<span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.PostMapping;
<span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RequestMapping;
<span class="hljs-keyword">import</span> org.springframework.web.multipart.MultipartFile;
 
<span class="hljs-keyword">import</span> javax.servlet.http.HttpServletRequest;
<span class="hljs-keyword">import</span> java.io.File;
<span class="hljs-keyword">import</span> java.io.IOException;
 
<span class="hljs-meta">@Controller</span>
<span class="hljs-meta">@RequestMapping(&quot;/file&quot;)</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FileHandler</span> </span>&#123;
 
    <span class="hljs-meta">@PostMapping(&quot;/upload&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">upload</span><span class="hljs-params">(MultipartFile img, HttpServletRequest request)</span></span>&#123;
        <span class="hljs-keyword">if</span>(img.getSize()&gt;<span class="hljs-number">0</span>)&#123;
            <span class="hljs-comment">//获取保存上传文件的file路径</span>
            String path = request.getServletContext().getRealPath(<span class="hljs-string">&quot;file&quot;</span>);
            <span class="hljs-comment">//获取上传的文件名</span>
            String name = img.getOriginalFilename();
            File file = <span class="hljs-keyword">new</span> File(path,name);
            <span class="hljs-keyword">try</span> &#123;
                img.transferTo(file);
                <span class="hljs-comment">//保存上传之后的文件路径</span>
                request.setAttribute(<span class="hljs-string">&quot;path&quot;</span>,<span class="hljs-string">&quot;/file/&quot;</span>+name);
            &#125; <span class="hljs-keyword">catch</span> (IOException e) &#123;
                e.printStackTrace();
            &#125;
        &#125;
        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;upload&quot;</span>;
    &#125;
&#125;</code></pre>

<ul>
<li>springmvc.xml</li>
</ul>
<pre><code class="hljs xml"><span class="hljs-comment">&lt;!-- 配置上传组件 --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;multipartResolver&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;org.springframework.web.multipart.commons.CommonsMultipartResolver&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span></code></pre>

<ul>
<li>web.xml 添加如下配置，否则客户端无法访问 png</li>
</ul>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">servlet-mapping</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">servlet-name</span>&gt;</span>default<span class="hljs-tag">&lt;/<span class="hljs-name">servlet-name</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">url-pattern</span>&gt;</span>*.png<span class="hljs-tag">&lt;/<span class="hljs-name">url-pattern</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">servlet-mapping</span>&gt;</span></code></pre>

<blockquote>
<p>多文件上传</p>
</blockquote>
<p>pom.xml</p>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>jstl<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>jstl<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.2<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>taglibs<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>standard<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.1.2<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></code></pre>

<p>JSP</p>
<pre><code class="hljs jsp">&lt;%--
  Created by IntelliJ IDEA.
  User: southwind
  Date: <span class="hljs-number">2019</span>-<span class="hljs-number">03</span>-<span class="hljs-number">15</span>
  Time: 09:<span class="hljs-number">32</span>
  To change <span class="hljs-keyword">this</span> template use File | Settings | File Templates.
--%&gt;
&lt;%@ page contentType=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span> language=<span class="hljs-string">&quot;java&quot;</span> %&gt;
&lt;%@ page isELIgnored=<span class="hljs-string">&quot;false&quot;</span> %&gt;
&lt;%@ taglib prefix=<span class="hljs-string">&quot;c&quot;</span> uri=<span class="hljs-string">&quot;http://java.sun.com/jsp/jstl/core&quot;</span> %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form action=<span class="hljs-string">&quot;/file/uploads&quot;</span> method=<span class="hljs-string">&quot;post&quot;</span> enctype=<span class="hljs-string">&quot;multipart/form-data&quot;</span>&gt;
        file1:&lt;input type=<span class="hljs-string">&quot;file&quot;</span> name=<span class="hljs-string">&quot;imgs&quot;</span>/&gt;&lt;br/&gt;
        file2:&lt;input type=<span class="hljs-string">&quot;file&quot;</span> name=<span class="hljs-string">&quot;imgs&quot;</span>/&gt;&lt;br/&gt;
        file3:&lt;input type=<span class="hljs-string">&quot;file&quot;</span> name=<span class="hljs-string">&quot;imgs&quot;</span>&gt;&lt;br/&gt;
        &lt;input type=<span class="hljs-string">&quot;submit&quot;</span> value=<span class="hljs-string">&quot;上传&quot;</span>/&gt;
    &lt;/form&gt;
    &lt;c:forEach items=<span class="hljs-string">&quot;$&#123;files&#125;&quot;</span> <span class="hljs-keyword">var</span>=<span class="hljs-string">&quot;file&quot;</span> &gt;
        &lt;img src=<span class="hljs-string">&quot;$&#123;file&#125;&quot;</span> width=<span class="hljs-string">&quot;300px&quot;</span>&gt;
    &lt;/c:forEach&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>

<p>Handler</p>
<pre><code class="hljs java"><span class="hljs-meta">@PostMapping(&quot;/uploads&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">uploads</span><span class="hljs-params">(MultipartFile[] imgs,HttpServletRequest request)</span></span>&#123;
    List&lt;String&gt; files = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;();
    <span class="hljs-keyword">for</span> (MultipartFile img:imgs)&#123;
        <span class="hljs-keyword">if</span>(img.getSize()&gt;<span class="hljs-number">0</span>)&#123;
            <span class="hljs-comment">//获取保存上传文件的file路径</span>
            String path = request.getServletContext().getRealPath(<span class="hljs-string">&quot;file&quot;</span>);
            <span class="hljs-comment">//获取上传的文件名</span>
            String name = img.getOriginalFilename();
            File file = <span class="hljs-keyword">new</span> File(path,name);
            <span class="hljs-keyword">try</span> &#123;
                img.transferTo(file);
                <span class="hljs-comment">//保存上传之后的文件路径</span>
                files.add(<span class="hljs-string">&quot;/file/&quot;</span>+name);
            &#125; <span class="hljs-keyword">catch</span> (IOException e) &#123;
                e.printStackTrace();
            &#125;
        &#125;
    &#125;
    request.setAttribute(<span class="hljs-string">&quot;files&quot;</span>,files);
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;uploads&quot;</span>;
&#125;</code></pre>

<blockquote>
<p>下载</p>
</blockquote>
<ul>
<li>JSP</li>
</ul>
<pre><code class="hljs jsp">&lt;%--
  Created by IntelliJ IDEA.
  User: southwind
  Date: <span class="hljs-number">2019</span>-<span class="hljs-number">03</span>-<span class="hljs-number">15</span>
  Time: <span class="hljs-number">10</span>:<span class="hljs-number">36</span>
  To change <span class="hljs-keyword">this</span> template use File | Settings | File Templates.
--%&gt;
&lt;%@ page contentType=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span> language=<span class="hljs-string">&quot;java&quot;</span> %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;a href=<span class="hljs-string">&quot;/file/download/1&quot;</span>&gt;<span class="hljs-number">1.</span>png&lt;/a&gt;
    &lt;a href=<span class="hljs-string">&quot;/file/download/2&quot;</span>&gt;<span class="hljs-number">2.</span>png&lt;/a&gt;
    &lt;a href=<span class="hljs-string">&quot;/file/download/3&quot;</span>&gt;<span class="hljs-number">3.</span>png&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>

<ul>
<li>Handler</li>
</ul>
<pre><code class="hljs java"><span class="hljs-meta">@GetMapping(&quot;/download/&#123;name&#125;&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">download</span><span class="hljs-params">(<span class="hljs-meta">@PathVariable(&quot;name&quot;)</span> String name, HttpServletRequest request, HttpServletResponse response)</span></span>&#123;
    <span class="hljs-keyword">if</span>(name != <span class="hljs-keyword">null</span>)&#123;
        name += <span class="hljs-string">&quot;.png&quot;</span>;
        String path = request.getServletContext().getRealPath(<span class="hljs-string">&quot;file&quot;</span>);
        File file = <span class="hljs-keyword">new</span> File(path,name);
        OutputStream outputStream = <span class="hljs-keyword">null</span>;
        <span class="hljs-keyword">if</span>(file.exists())&#123;
            response.setContentType(<span class="hljs-string">&quot;application/forc-download&quot;</span>);
            response.setHeader(<span class="hljs-string">&quot;Content-Disposition&quot;</span>,<span class="hljs-string">&quot;attachment;filename=&quot;</span>+name);
            <span class="hljs-keyword">try</span> &#123;
                outputStream = response.getOutputStream();
                outputStream.write(FileUtils.readFileToByteArray(file));
                outputStream.flush();
            &#125; <span class="hljs-keyword">catch</span> (IOException e) &#123;
                e.printStackTrace();
            &#125; <span class="hljs-keyword">finally</span> &#123;
                <span class="hljs-keyword">if</span>(outputStream != <span class="hljs-keyword">null</span>)&#123;
                    <span class="hljs-keyword">try</span> &#123;
                        outputStream.close();
                    &#125; <span class="hljs-keyword">catch</span> (IOException e) &#123;
                        e.printStackTrace();
                    &#125;
                &#125;
            &#125;
        &#125;
    &#125;
&#125;</code></pre>

<h3 id="Spring-MVC-表单标签库"><a href="#Spring-MVC-表单标签库" class="headerlink" title="Spring MVC 表单标签库"></a>Spring MVC 表单标签库</h3><ul>
<li>Handler</li>
</ul>
<pre><code class="hljs java"><span class="hljs-meta">@GetMapping(&quot;/get&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> ModelAndView <span class="hljs-title">get</span><span class="hljs-params">()</span></span>&#123;
    ModelAndView modelAndView = <span class="hljs-keyword">new</span> ModelAndView(<span class="hljs-string">&quot;tag&quot;</span>);
    Student student = <span class="hljs-keyword">new</span> Student(<span class="hljs-number">1L</span>,<span class="hljs-string">&quot;张三&quot;</span>,<span class="hljs-number">22</span>);
    modelAndView.addObject(<span class="hljs-string">&quot;student&quot;</span>,student);
    <span class="hljs-keyword">return</span> modelAndView;
&#125;</code></pre>

<ul>
<li>JSP</li>
</ul>
<pre><code class="hljs jsp">&lt;%--
  Created by IntelliJ IDEA.
  User: southwind
  Date: <span class="hljs-number">2019</span>-<span class="hljs-number">03</span>-<span class="hljs-number">15</span>
  Time: <span class="hljs-number">10</span>:<span class="hljs-number">53</span>
  To change <span class="hljs-keyword">this</span> template use File | Settings | File Templates.
--%&gt;
&lt;%@ page contentType=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span> language=<span class="hljs-string">&quot;java&quot;</span> %&gt;
&lt;%@ page isELIgnored=<span class="hljs-string">&quot;false&quot;</span> %&gt;
&lt;%@ taglib prefix=<span class="hljs-string">&quot;form&quot;</span> uri=<span class="hljs-string">&quot;http://www.springframework.org/tags/form&quot;</span> %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;学生信息&lt;/h1&gt;
    &lt;form:form modelAttribute=<span class="hljs-string">&quot;student&quot;</span>&gt;
        学生ID：&lt;form:input path=<span class="hljs-string">&quot;id&quot;</span>/&gt;&lt;br/&gt;
        学生姓名：&lt;form:input path=<span class="hljs-string">&quot;name&quot;</span>/&gt;&lt;br/&gt;
        学生年龄：&lt;form:input path=<span class="hljs-string">&quot;age&quot;</span>/&gt;&lt;br/&gt;
        &lt;input type=<span class="hljs-string">&quot;submit&quot;</span> value=<span class="hljs-string">&quot;提交&quot;</span>/&gt;
    &lt;/form:form&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>

<p>1、JSP 页面导入 Spring MVC 表单标签库，与导入 JSTL 标签库的语法非常相似，前缀 prefix 可以自定义，通常定义为 from。</p>
<pre><code class="hljs jsp">&lt;%@ taglib prefix=<span class="hljs-string">&quot;form&quot;</span> uri=<span class="hljs-string">&quot;http://www.springframework.org/tags/form&quot;</span> %&gt;</code></pre>

<p>2、将 form 表单与模型数据进行绑定，通过 modelAttribute 属性完成绑定，将 modelAttribute 的值设置为模型数据对应的 key 值。</p>
<pre><code class="hljs java">Handeler:modelAndView.addObject(<span class="hljs-string">&quot;student&quot;</span>,student);
JSP:&lt;form:form modelAttribute=<span class="hljs-string">&quot;student&quot;</span>&gt;</code></pre>

<p>3、form 表单完成绑定之后，将模型数据的值取出绑定到不同的标签中，通过设置标签的 path 属性完成，将 path 属性的值设置为模型数据对应的属性名即可。</p>
<pre><code class="hljs jsp">学生ID：&lt;form:input path=<span class="hljs-string">&quot;id&quot;</span>/&gt;&lt;br/&gt;
学生姓名：&lt;form:input path=<span class="hljs-string">&quot;name&quot;</span>/&gt;&lt;br/&gt;
学生年龄：&lt;form:input path=<span class="hljs-string">&quot;age&quot;</span>/&gt;&lt;br/&gt;</code></pre>

<h4 id="常用的表单标签"><a href="#常用的表单标签" class="headerlink" title="常用的表单标签"></a>常用的表单标签</h4><ul>
<li>from</li>
</ul>
<pre><code class="hljs jsp">&lt;form:from modelAttribute=<span class="hljs-string">&quot;student&quot;</span>/&gt;</code></pre>

<p>渲染的是 HTML 中的<code>&lt;form&gt;&lt;/from&gt;</code>，通过 modelAttribute 属性绑定具体的模型数据。</p>
<ul>
<li>input</li>
</ul>
<pre><code class="hljs jsp">&lt;form:input path=<span class="hljs-string">&quot;name&quot;</span>/&gt;</code></pre>

<p>渲染的是 HTML 中的 <code>&lt;input type=&quot;text&quot;/&gt;</code>，from 标签绑定的是模型数据，input 标签绑定的是模型数据中的属性值，通过 path 属性可以与模型数据中的属性名对应，并且支持及联操作。</p>
<pre><code class="hljs jsp">&lt;from:input path=<span class="hljs-string">&quot;address.name&quot;</span>/&gt;</code></pre>

<ul>
<li>password</li>
</ul>
<pre><code class="hljs jsp">&lt;form:password path=<span class="hljs-string">&quot;password&quot;</span>/&gt;</code></pre>

<p>渲染的是 HTML 中的 <code>&lt;input type=&quot;password&quot;/&gt;</code>，通过 path 属性与模型数据的属性值进行绑定，password 标签的值不会在页面显示。</p>
<ul>
<li>checkbox</li>
</ul>
<pre><code class="hljs jsp">&lt;form:checkbox path=<span class="hljs-string">&quot;hobby&quot;</span> value=<span class="hljs-string">&quot;读书&quot;</span>/&gt;</code></pre>

<pre><code class="hljs java">student.setFlag(<span class="hljs-keyword">false</span>);</code></pre>

<pre><code class="hljs jsp">checkbox：&lt;form:checkbox path=<span class="hljs-string">&quot;flag&quot;</span> value=<span class="hljs-string">&quot;flag&quot;</span>&gt;&lt;/form:checkbox&gt;&lt;br/&gt;</code></pre>

<p>渲染的是 HTML 中的 <code>&lt;input type=&quot;checkbox&quot;/&gt;</code>，通过 path 与模型数据的属性值进行绑定，可以绑定 boolean、数组和集合。</p>
<p>如果绑定 boolean 值，若该变量的值为 true，则表示该复选框选中，否则表示不选中。</p>
<p>如果绑定数组或者集合，数组/集合中的元素等于 checkbox 的 value 值，则选中。</p>
<pre><code class="hljs java">student.setHobby(Arrays.asList(<span class="hljs-string">&quot;读书&quot;</span>,<span class="hljs-string">&quot;看电影&quot;</span>,<span class="hljs-string">&quot;玩游戏&quot;</span>));
modelAndView.addObject(<span class="hljs-string">&quot;student&quot;</span>,student);</code></pre>

<pre><code class="hljs jsp">爱好：&lt;form:checkbox path=<span class="hljs-string">&quot;hobby&quot;</span> value=<span class="hljs-string">&quot;摄影&quot;</span>&gt;&lt;/form:checkbox&gt;摄影&lt;br/&gt;
&lt;form:checkbox path=<span class="hljs-string">&quot;hobby&quot;</span> value=<span class="hljs-string">&quot;读书&quot;</span>&gt;&lt;/form:checkbox&gt;读书&lt;br/&gt;
&lt;form:checkbox path=<span class="hljs-string">&quot;hobby&quot;</span> value=<span class="hljs-string">&quot;听音乐&quot;</span>&gt;&lt;/form:checkbox&gt;听音乐&lt;br/&gt;
&lt;form:checkbox path=<span class="hljs-string">&quot;hobby&quot;</span> value=<span class="hljs-string">&quot;看电影&quot;</span>&gt;&lt;/form:checkbox&gt;看电影&lt;br/&gt;
&lt;form:checkbox path=<span class="hljs-string">&quot;hobby&quot;</span> value=<span class="hljs-string">&quot;旅游&quot;</span>&gt;&lt;/form:checkbox&gt;旅游&lt;br/&gt;
&lt;form:checkbox path=<span class="hljs-string">&quot;hobby&quot;</span> value=<span class="hljs-string">&quot;玩游戏&quot;</span>&gt;&lt;/form:checkbox&gt;玩游戏&lt;br/&gt;
&lt;input type=<span class="hljs-string">&quot;submit&quot;</span> value=<span class="hljs-string">&quot;提交&quot;</span>/&gt;</code></pre>

<ul>
<li>checkboxes</li>
</ul>
<pre><code class="hljs jsp">&lt;form:checkboxes items=$&#123;student.hobby&#125; path=<span class="hljs-string">&quot;selecHobby&quot;</span>/&gt;</code></pre>

<p>渲染的是 HTML 中的一组 <code>&lt;input type=&quot;checkbox&quot;/&gt;</code>，是对 <code>&lt;form:checkbox/&gt;</code> 的一种简化，需要结合 items 和 path 属性来使用，items 绑定被遍历的集合或数组，path 绑定被选中的集合或数组，可以这样理解，items 为全部可选集合，path 为默认的选中集合。</p>
<pre><code class="hljs java">student.setHobby(Arrays.asList(<span class="hljs-string">&quot;摄影&quot;</span>,<span class="hljs-string">&quot;读书&quot;</span>,<span class="hljs-string">&quot;听音乐&quot;</span>,<span class="hljs-string">&quot;看电影&quot;</span>,<span class="hljs-string">&quot;旅游&quot;</span>,<span class="hljs-string">&quot;玩游戏&quot;</span>));
student.setSelectHobby(Arrays.asList(<span class="hljs-string">&quot;摄影&quot;</span>,<span class="hljs-string">&quot;读书&quot;</span>,<span class="hljs-string">&quot;听音乐&quot;</span>));
modelAndView.addObject(<span class="hljs-string">&quot;student&quot;</span>,student);</code></pre>

<pre><code class="hljs jsp">爱好：&lt;form:checkboxes path=<span class="hljs-string">&quot;selectHobby&quot;</span> items=<span class="hljs-string">&quot;$&#123;student.hobby&#125;&quot;</span>/&gt;&lt;br/&gt;</code></pre>

<p>需要注意的是 path 可以直接绑定模型数据的属性值，items 则需要通过 EL 表达式的形式从域对象中获取数据，不能直接写属性名。</p>
<ul>
<li>rabiobutton</li>
</ul>
<pre><code class="hljs jsp">&lt;from:radiobutton path=<span class="hljs-string">&quot;radioId&quot;</span> value=<span class="hljs-string">&quot;0&quot;</span>/&gt;</code></pre>

<p>渲染的是 HTML 中的一个 <code>&lt;input type=&quot;radio&quot;/&gt;</code>，绑定的数据与标签的 value 值相等则为选中，否则不选中。</p>
<pre><code class="hljs java">student.setRadioId(<span class="hljs-number">1</span>);
modelAndView.addObject(<span class="hljs-string">&quot;student&quot;</span>,student);</code></pre>

<pre><code class="hljs jsp">radiobutton:&lt;form:radiobutton path=<span class="hljs-string">&quot;radioId&quot;</span> value=<span class="hljs-string">&quot;1&quot;</span>/&gt;radiobutton&lt;br/&gt;</code></pre>

<ul>
<li>radiobuttons</li>
</ul>
<pre><code class="hljs jsp">&lt;form:radiobuttons itmes=<span class="hljs-string">&quot;$&#123;student.grade&#125;&quot;</span> path=<span class="hljs-string">&quot;selectGrade&quot;</span>/&gt;</code></pre>

<p>渲染的是 HTML 中的一组 <code>&lt;input type=&quot;radio&quot;/&gt;</code>，这里需要结合 items 和 path 两个属性来使用，items 绑定被遍历的集合或数组，path 绑定被选中的值，items 为全部的可选类型，path 为默认选中的选项，用法与 <code>&lt;form:checkboxes/&gt;</code> 一致。</p>
<pre><code class="hljs java">Map&lt;Integer,String&gt; gradeMap = <span class="hljs-keyword">new</span> HashMap&lt;&gt;();
gradeMap.put(<span class="hljs-number">1</span>,<span class="hljs-string">&quot;一年级&quot;</span>);
gradeMap.put(<span class="hljs-number">2</span>,<span class="hljs-string">&quot;二年级&quot;</span>);
gradeMap.put(<span class="hljs-number">3</span>,<span class="hljs-string">&quot;三年级&quot;</span>);
gradeMap.put(<span class="hljs-number">4</span>,<span class="hljs-string">&quot;四年级&quot;</span>);
gradeMap.put(<span class="hljs-number">5</span>,<span class="hljs-string">&quot;五年级&quot;</span>);
gradeMap.put(<span class="hljs-number">6</span>,<span class="hljs-string">&quot;六年级&quot;</span>);
student.setGradeMap(gradeMap);
student.setSelectGrade(<span class="hljs-number">3</span>);
modelAndView.addObject(<span class="hljs-string">&quot;student&quot;</span>,student);</code></pre>

<pre><code class="hljs jsp">学生年级：&lt;form:radiobuttons items=<span class="hljs-string">&quot;$&#123;student.gradeMap&#125;&quot;</span> path=<span class="hljs-string">&quot;selectGrade&quot;</span>/&gt;&lt;br/&gt;</code></pre>

<ul>
<li>select</li>
</ul>
<pre><code class="hljs jsp">&lt;form:select items=<span class="hljs-string">&quot;$&#123;student.citys&#125;&quot;</span> path=<span class="hljs-string">&quot;selectCity&quot;</span>/&gt;</code></pre>

<p>渲染的是 HTML 中的一个 <code>&lt;select/&gt;</code> 标签，需要结合 items 和 path 两个属性来使用，items 绑定被遍历的集合或数组，path 绑定被选中的值，用法与 <code>&lt;from:radiobuttons/&gt;</code>一致。</p>
<pre><code class="hljs java">Map&lt;Integer,String&gt; cityMap = <span class="hljs-keyword">new</span> HashMap&lt;&gt;();
cityMap.put(<span class="hljs-number">1</span>,<span class="hljs-string">&quot;北京&quot;</span>);
cityMap.put(<span class="hljs-number">2</span>,<span class="hljs-string">&quot;上海&quot;</span>);
cityMap.put(<span class="hljs-number">3</span>,<span class="hljs-string">&quot;广州&quot;</span>);
cityMap.put(<span class="hljs-number">4</span>,<span class="hljs-string">&quot;深圳&quot;</span>);
student.setCityMap(cityMap);
student.setSelectCity(<span class="hljs-number">3</span>);
modelAndView.addObject(<span class="hljs-string">&quot;student&quot;</span>,student);</code></pre>

<pre><code class="hljs jsp">所在城市：&lt;form:select items=<span class="hljs-string">&quot;$&#123;student.cityMap&#125;&quot;</span> path=<span class="hljs-string">&quot;selectCity&quot;</span>&gt;&lt;/form:select&gt;&lt;br/&gt;</code></pre>

<ul>
<li>options</li>
</ul>
<p><code>form:select</code> 结合 <code>form:options</code> 的使用，<code>from:select</code> 只定义 path 属性，在 <code>form:select</code> 标签内部添加一个子标签 <code>form:options</code> ，设置 items 属性，获取被遍历的集合。</p>
<pre><code class="hljs jsp">所在城市：&lt;form:select path=<span class="hljs-string">&quot;selectCity&quot;</span>&gt;
                &lt;form:options items=<span class="hljs-string">&quot;$&#123;student.cityMap&#125;&quot;</span>&gt;&lt;/form:options&gt;
                &lt;/form:select&gt;&lt;br/&gt;</code></pre>

<ul>
<li><p>option</p>
<p><code>form:select</code> 结合 <code>form:option</code> 的使用，<code>from:select</code> 定义 path 属性，给每一个 <code>form:option</code> 设置 value 值，path 的值与哪个 value 值相等，该项默认选中。</p>
</li>
</ul>
<pre><code class="hljs jsp">所在城市：&lt;form:select path=<span class="hljs-string">&quot;selectCity&quot;</span>&gt;
            &lt;form:option value=<span class="hljs-string">&quot;1&quot;</span>&gt;杭州&lt;/form:option&gt;
            &lt;form:option value=<span class="hljs-string">&quot;2&quot;</span>&gt;成都&lt;/form:option&gt;
            &lt;form:option value=<span class="hljs-string">&quot;3&quot;</span>&gt;西安&lt;/form:option&gt;
        &lt;/form:select&gt;&lt;br/&gt;</code></pre>

<ul>
<li>textarea</li>
</ul>
<p>渲染的是 HTML 中的一个 <code>&lt;textarea/&gt;</code> ，path 绑定模型数据的属性值，作为文本输入域的默认值。</p>
<pre><code class="hljs java">student.setIntroduce(<span class="hljs-string">&quot;你好，我是...&quot;</span>);
modelAndView.addObject(<span class="hljs-string">&quot;student&quot;</span>,student);</code></pre>

<pre><code class="hljs jsp">信息：&lt;form:textarea path=<span class="hljs-string">&quot;introduce&quot;</span>/&gt;&lt;br/&gt;</code></pre>

<ul>
<li>errors</li>
</ul>
<p>处理错误信息，一般用在数据校验，该标签需要结合 Spring MVC 的验证器结合起来使用。</p>
<h3 id="Spring-MVC-数据校验"><a href="#Spring-MVC-数据校验" class="headerlink" title="Spring MVC 数据校验"></a>Spring MVC 数据校验</h3><p>Spring MVC 提供了两种数据校验的方式：1、基于 Validator 接口。2、使用 Annotation JSR - 303 标准进行校验。</p>
<p>基于 Validator 接口的方式需要自定义 Validator 验证器，每一条数据的验证规则需要开发者手动完成，使用 Annotation JSR - 303 标准则不需要自定义验证器，通过注解的方式可以直接在实体类中添加每个属性的验证规则，这种方式更加方便，实际开发中推荐使用。</p>
<blockquote>
<p>基于 Validator 接口</p>
</blockquote>
<ul>
<li>实体类 Account</li>
</ul>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.entity;
 
<span class="hljs-keyword">import</span> lombok.Data;
 
<span class="hljs-meta">@Data</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Account</span> </span>&#123;
    <span class="hljs-keyword">private</span> String name;
    <span class="hljs-keyword">private</span> String password;
&#125;</code></pre>

<ul>
<li>自定义验证器 AccountValidator，实现 Validator 接口。</li>
</ul>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.validator;
 
<span class="hljs-keyword">import</span> com.southwind.entity.Account;
<span class="hljs-keyword">import</span> org.springframework.validation.Errors;
<span class="hljs-keyword">import</span> org.springframework.validation.ValidationUtils;
<span class="hljs-keyword">import</span> org.springframework.validation.Validator;
 
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AccountValidator</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Validator</span> </span>&#123;
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">supports</span><span class="hljs-params">(Class&lt;?&gt; aClass)</span> </span>&#123;
        <span class="hljs-keyword">return</span> Account.class.equals(aClass);
    &#125;
 
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">validate</span><span class="hljs-params">(Object o, Errors errors)</span> </span>&#123;
        ValidationUtils.rejectIfEmpty(errors,<span class="hljs-string">&quot;name&quot;</span>,<span class="hljs-keyword">null</span>,<span class="hljs-string">&quot;姓名不能为空&quot;</span>);
        ValidationUtils.rejectIfEmpty(errors,<span class="hljs-string">&quot;password&quot;</span>,<span class="hljs-keyword">null</span>,<span class="hljs-string">&quot;密码不能为空&quot;</span>);
    &#125;
&#125;</code></pre>

<ul>
<li>控制器</li>
</ul>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.controller;
 
<span class="hljs-keyword">import</span> com.southwind.entity.Account;
<span class="hljs-keyword">import</span> org.springframework.stereotype.Controller;
<span class="hljs-keyword">import</span> org.springframework.ui.Model;
<span class="hljs-keyword">import</span> org.springframework.validation.BindingResult;
<span class="hljs-keyword">import</span> org.springframework.validation.annotation.Validated;
<span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.GetMapping;
<span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.PostMapping;
<span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RequestMapping;
 
<span class="hljs-meta">@Controller</span>
<span class="hljs-meta">@RequestMapping(&quot;/validator&quot;)</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ValidatorHandler</span> </span>&#123;
 
    <span class="hljs-meta">@GetMapping(&quot;/login&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">login</span><span class="hljs-params">(Model model)</span></span>&#123;
        model.addAttribute(<span class="hljs-string">&quot;account&quot;</span>,<span class="hljs-keyword">new</span> Account());
        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;login&quot;</span>;
    &#125;
 
    <span class="hljs-meta">@PostMapping(&quot;/login&quot;)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">login</span><span class="hljs-params">(<span class="hljs-meta">@Validated</span> Account account, BindingResult bindingResult)</span></span>&#123;
        <span class="hljs-keyword">if</span>(bindingResult.hasErrors())&#123;
            <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;login&quot;</span>;
        &#125;
        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;index&quot;</span>;
    &#125;
&#125;</code></pre>

<ul>
<li>springmvc.xml 配置验证器。</li>
</ul>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;accountValidator&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;com.southwind.validator.AccountValidator&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">bean</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">mvc:annotation-driven</span> <span class="hljs-attr">validator</span>=<span class="hljs-string">&quot;accountValidator&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">mvc:annotation-driven</span>&gt;</span></code></pre>

<ul>
<li>JSP</li>
</ul>
<pre><code class="hljs jsp">&lt;%--
  Created by IntelliJ IDEA.
  User: southwind
  Date: <span class="hljs-number">2019</span>-<span class="hljs-number">03</span>-<span class="hljs-number">18</span>
  Time: <span class="hljs-number">10</span>:<span class="hljs-number">31</span>
  To change <span class="hljs-keyword">this</span> template use File | Settings | File Templates.
--%&gt;
&lt;%@ page contentType=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span> language=<span class="hljs-string">&quot;java&quot;</span> %&gt;
&lt;%@ page isELIgnored=<span class="hljs-string">&quot;false&quot;</span> %&gt;
&lt;%@ taglib prefix=<span class="hljs-string">&quot;form&quot;</span> uri=<span class="hljs-string">&quot;http://www.springframework.org/tags/form&quot;</span> %&gt;
&lt;%@ taglib prefix=<span class="hljs-string">&quot;from&quot;</span> uri=<span class="hljs-string">&quot;http://www.springframework.org/tags/form&quot;</span> %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form:form modelAttribute=<span class="hljs-string">&quot;account&quot;</span> action=<span class="hljs-string">&quot;/validator/login&quot;</span> method=<span class="hljs-string">&quot;post&quot;</span>&gt;
        姓名：&lt;form:input path=<span class="hljs-string">&quot;name&quot;</span>/&gt;&lt;from:errors path=<span class="hljs-string">&quot;name&quot;</span>&gt;&lt;/from:errors&gt;&lt;br/&gt;
        密码：&lt;form:input path=<span class="hljs-string">&quot;password&quot;</span>/&gt;&lt;from:errors path=<span class="hljs-string">&quot;password&quot;</span>&gt;&lt;/from:errors&gt;&lt;br/&gt;
        &lt;input type=<span class="hljs-string">&quot;submit&quot;</span> value=<span class="hljs-string">&quot;登录&quot;</span>/&gt;
    &lt;/form:form&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>

<blockquote>
<p>Annotation JSR - 303 标准</p>
</blockquote>
<p>使用 Annotation JSR - 303 标准进行验证，需要导入支持这种标准的依赖 jar 文件，这里我们使用 Hibernate Validator。</p>
<ul>
<li>pom.xml</li>
</ul>
<pre><code class="hljs xml"><span class="hljs-comment">&lt;!-- JSR-303 --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.hibernate<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>hibernate-validator<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>5.3.6.Final<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>javax.validation<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>validation-api<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.0.1.Final<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
 
<span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.jboss.logging<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>jboss-logging<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>3.3.2.Final<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></code></pre>

<ul>
<li>通过注解的方式直接在实体类中添加相关的验证规则。</li>
</ul>
<pre><code class="hljs java"><span class="hljs-keyword">package</span> com.southwind.entity;
 
<span class="hljs-keyword">import</span> lombok.Data;
<span class="hljs-keyword">import</span> org.hibernate.validator.constraints.Email;
<span class="hljs-keyword">import</span> org.hibernate.validator.constraints.NotEmpty;
<span class="hljs-keyword">import</span> javax.validation.constraints.Pattern;
<span class="hljs-keyword">import</span> javax.validation.constraints.Size;
 
<span class="hljs-meta">@Data</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span> </span>&#123;
    <span class="hljs-meta">@NotEmpty(message = &quot;用户名不能为空&quot;)</span>
    <span class="hljs-keyword">private</span> String username;
    <span class="hljs-meta">@Size(min = 6,max = 12,message = &quot;密码6-12位&quot;)</span>
    <span class="hljs-keyword">private</span> String password;
    <span class="hljs-meta">@Email(regexp = &quot;^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\\\.[a-zA-Z0-9-]+)*\\\\.[a-zA-Z0-9]&#123;2,6&#125;$&quot;,message = &quot;请输入正确的邮箱格式&quot;)</span>
    <span class="hljs-keyword">private</span> String email;
    <span class="hljs-meta">@Pattern(regexp = &quot;^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\\\\\\\d&#123;8&#125;$&quot;,message = &quot;请输入正确的电话&quot;)</span>
    <span class="hljs-keyword">private</span> String phone;
&#125;</code></pre>

<ul>
<li>ValidatorHandler</li>
</ul>
<pre><code class="hljs java"><span class="hljs-meta">@GetMapping(&quot;/register&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">register</span><span class="hljs-params">(Model model)</span></span>&#123;
    model.addAttribute(<span class="hljs-string">&quot;person&quot;</span>,<span class="hljs-keyword">new</span> Person());
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;register&quot;</span>;
&#125;
 
<span class="hljs-meta">@PostMapping(&quot;/register&quot;)</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">register</span><span class="hljs-params">(<span class="hljs-meta">@Valid</span> Person person, BindingResult bindingResult)</span></span>&#123;
    <span class="hljs-keyword">if</span>(bindingResult.hasErrors())&#123;
        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;register&quot;</span>;
    &#125;
    <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;index&quot;</span>;
&#125;</code></pre>

<ul>
<li>springmvc.xml</li>
</ul>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">mvc:annotation-driven</span> /&gt;</span></code></pre>

<ul>
<li>JSP</li>
</ul>
<pre><code class="hljs jsp">&lt;%--
  Created by IntelliJ IDEA.
  User: southwind
  Date: <span class="hljs-number">2019</span>-<span class="hljs-number">03</span>-<span class="hljs-number">18</span>
  Time: <span class="hljs-number">11</span>:<span class="hljs-number">29</span>
  To change <span class="hljs-keyword">this</span> template use File | Settings | File Templates.
--%&gt;
&lt;%@ page contentType=<span class="hljs-string">&quot;text/html;charset=UTF-8&quot;</span> language=<span class="hljs-string">&quot;java&quot;</span> %&gt;
&lt;%@ page isELIgnored=<span class="hljs-string">&quot;false&quot;</span> %&gt;
&lt;%@ taglib prefix=<span class="hljs-string">&quot;form&quot;</span> uri=<span class="hljs-string">&quot;http://www.springframework.org/tags/form&quot;</span> %&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form:form modelAttribute=<span class="hljs-string">&quot;person&quot;</span> action=<span class="hljs-string">&quot;/validator/register2&quot;</span> method=<span class="hljs-string">&quot;post&quot;</span>&gt;
        用户名：&lt;form:input path=<span class="hljs-string">&quot;username&quot;</span>&gt;&lt;/form:input&gt;&lt;form:errors path=<span class="hljs-string">&quot;username&quot;</span>/&gt;&lt;br/&gt;
        密码：&lt;form:password path=<span class="hljs-string">&quot;password&quot;</span>&gt;&lt;/form:password&gt;&lt;form:errors path=<span class="hljs-string">&quot;password&quot;</span>/&gt;&lt;br/&gt;
        邮箱：&lt;form:input path=<span class="hljs-string">&quot;email&quot;</span>&gt;&lt;/form:input&gt;&lt;form:errors path=<span class="hljs-string">&quot;email&quot;</span>/&gt;&lt;br/&gt;
        电话：&lt;form:input path=<span class="hljs-string">&quot;phone&quot;</span>&gt;&lt;/form:input&gt;&lt;form:errors path=<span class="hljs-string">&quot;phone&quot;</span>/&gt;&lt;br/&gt;
        &lt;input type=<span class="hljs-string">&quot;submit&quot;</span> value=<span class="hljs-string">&quot;提交&quot;</span>/&gt;
    &lt;/form:form&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>

<p>校验规则详解：</p>
<p>@Null                   被注解的元素必须为null</p>
<p>@NotNull                  被注解的元素不能为null</p>
<p>@Min(value)              被注解的元素必须是一个数字，其值必须大于等于指定的最小值</p>
<p>@Max(value)             被注解的元素必须是一个数字，其值必须小于于等于指定的最大值   </p>
<p>@Email                   被注解的元素必须是电子邮箱地址</p>
<p>@Pattern                  被注解的元素必须符合对应的正则表达式</p>
<p>@Length                被注解的元素的大小必须在指定的范围内</p>
<p>@NotEmpty                 被注解的字符串的值必须非空</p>
<p>Null 和 Empty 是不同的结果，String str = null，str 是 null，String str = “”，str 不是 null，其值为空。</p>

    </div>
     
    <div class="post-footer__meta"><p>更新于 2022-04-09</p></div> 
    <div class="post-entry__tags"><a href="/tags/Spring-MVC/" class="post-tags__link button"># Spring MVC</a></div> 
</article>


    <div class="nav">
        <div class="nav__prev">
            
                <a href="/2022/04/12/%E7%BB%84%E4%BB%B6%E9%97%B4%E9%80%9A%E4%BF%A1/" class="nav__link">
                    <div>
                        <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M589.088 790.624L310.464 512l278.624-278.624 45.248 45.248L400.96 512l233.376 233.376z" fill="#808080"></path></svg>
                    </div>
                    <div>
                        <div class="nav__label">
                            <!-- Previous Post -->
                            上一页
                        </div>
                        <div class="nav__title">
                            组件间通信
                        </div>
                    </div>
                </a>
            
        </div>
        <div class="nav__next">
            
                <a href="/2022/04/07/Spring%E7%AC%94%E8%AE%B0/" class="nav__link">
                    <div>
                        <div class="nav__label">
                            <!-- Next Post -->
                            下一页
                        </div>
                        <div class="nav__title">
                            Spring
                        </div>
                    </div>
                    <div>
                        <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M434.944 790.624l-45.248-45.248L623.04 512l-233.376-233.376 45.248-45.248L713.568 512z" fill="#808080"></path></svg>
                    </div>
                </a>
            
        </div>
    </div>



    <div class="post__comments content-card" id="comment">
        
    <h4>评论</h4>
    
    
    
    <div id="valine_container" class="valine_thread"></div>

    
    
    
    
    
    
    
    


    </div>



</main>

            <footer class="footer" style="font-size: 10px;">
     
    <a href="#" class="button" id="b2t" aria-label="回到顶部" title="回到顶部">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="32" height="32">
            <path d="M233.376 722.752L278.624 768 512 534.624 745.376 768l45.248-45.248L512 444.128zM192 352h640V288H192z" fill="currentColor"></path>
        </svg>
    </a>

    


    
    
    
        <span id="busuanzi_container_site_uv" hidden>
            <span>游客:</span>
            <span id="busuanzi_value_site_uv"></span>
            <span></span>
            
                <span> </span>
            
        </span>
    
    
        <span id="busuanzi_container_site_pv" hidden>
            <span>次数:</span>
            <span id="busuanzi_value_site_pv"></span>
            <span></span>
            
        </span>
    
 
 

 
    
    
    <p>
        <!-- Powered by <a href="https://hexo.io" target="_blank">Hexo</a> | Theme - <a href="https://github.com/ChrAlpha/hexo-theme-cards" target="_blank">Cards</a> -->
        <span style="color: black;">作者：张程</span>
    </p>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
    </script>
    <script>
        var a_idx = 0;
            jQuery(document).ready(function($) {
                $("body").click(function(e) {
                    var a = new Array("会当凌绝顶，一览众山小", "春蚕到死丝方尽，蜡炬成灰泪始干", "夕阳无限好，只是近黄昏",
                     "位卑未敢忘忧国", "纸上得来终觉浅，绝知此事要躬行", "人生自古谁无死，留取丹心照汗青", "山重水复疑无路，柳暗花明又一村" ,
                     "小荷才露尖尖角，早有蜻蜓立上头", "床前明月光，疑是地上霜", "春色满园关不住，一枝红杏出墙来", 
                     "山际见来烟，竹中窥落日", "道狭草木长，夕露沾我衣","天长地久有时尽，此恨绵绵无绝期");
                    var color = new Array("#7B7B7B", "#CE0000", "#FF0080","#E800E8","#921AFF","#2828FF",
                    "#0072E3","#00CACA","#02DF82","#00DB00","#8CEA00","#E1E100","#EAC100","#F75000"
                    ,"#B87070","#AFAF61","#6FB7B7","#9999CC","#B766AD");
                    var $i = $("<a href='#' style='text-decoration:none'/>").text(a[a_idx]);
                    a_idx = (a_idx + 1) % a.length;
                    var x = e.pageX,
                        y = e.pageY;
                    $i.css({
                        "z-index": 999999999999999999999999999999999999999999999999999999999999999999999,
                        "top": y - 20,
                        "left": x,
                        "position": "absolute",
                        "font-weight": "bold",
                        "color": color[Math.floor(Math.random()*color.length)]
                    });
                    $("body").append($i);
                    $i.animate({
                            "top": y - 180,
                            "opacity": 0
                        },
                        1500,
                        function() {
                            $i.remove();
                        });
                });
            });
        </script>
    <script>
        !function() {
            function o(w, v, i) {
                return w.getAttribute(v) || i
            }
            function j(i) {
                return document.getElementsByTagName(i)
            }
            function l() {
                var i = j("script"),
                w = i.length,
                v = i[w - 1];
                return {
                    l: w,
                    z: o(v, "zIndex", -1),
                    o: o(v, "opacity", 0.5),
                    c: o(v, "color", "0,0,0"),
                    n: o(v, "count", 99)
                }
            }
            function k() {
                r = u.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
                n = u.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
            }
            function b() {
                e.clearRect(0, 0, r, n);
                var w = [f].concat(t);
                var x, v, A, B, z, y;
                t.forEach(function(i) {
                    i.x += i.xa,
                    i.y += i.ya,
                    i.xa *= i.x > r || i.x < 0 ? -1 : 1,
                    i.ya *= i.y > n || i.y < 0 ? -1 : 1,
                    e.fillRect(i.x - 0.5, i.y - 0.5, 1, 1);
                    for (v = 0; v < w.length; v++) {
                        x = w[v];
                        if (i !== x && null !== x.x && null !== x.y) {
                            B = i.x - x.x,
                            z = i.y - x.y,
                            y = B * B + z * z;
                            y < x.max && (x === f && y >= x.max / 2 && (i.x -= 0.03 * B, i.y -= 0.03 * z), A = (x.max - y) / x.max, e.beginPath(), e.lineWidth = A / 2, e.strokeStyle = "rgba(" + s.c + "," + (A + 0.2) + ")", e.moveTo(i.x, i.y), e.lineTo(x.x, x.y), e.stroke())
                        }
                    }
                    w.splice(w.indexOf(i), 1)
                }),
                m(b)
            }
            var u = document.createElement("canvas"),
            s = l(),
            c = "c_n" + s.l,
            e = u.getContext("2d"),
            r,
            n,
            m = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
            function(i) {
                window.setTimeout(i, 1000 / 45)
            },
            a = Math.random,
            f = {
                x: null,
                y: null,
                max: 20000
            };
            u.id = c;
            u.style.cssText = "position:fixed;top:0;left:0;z-index:" + s.z + ";opacity:" + s.o;
            j("body")[0].appendChild(u);
            k(),
            window.onresize = k;
            window.onmousemove = function(i) {
                i = i || window.event,
                f.x = i.clientX,
                f.y = i.clientY
            },
            window.onmouseout = function() {
                f.x = null,
                f.y = null
            };
            for (var t = [], p = 0; s.n > p; p++) {
                var h = a() * r,
                g = a() * n,
                q = 2 * a() - 1,
                d = 2 * a() - 1;
                t.push({
                    x: h,
                    y: g,
                    xa: q,
                    ya: d,
                    max: 6000
                })
            }
            setTimeout(function() {
                b()
            }, 100)
    } ();
    </script>
</footer>

        </div>
        
    <script defer src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@17.1.0/dist/lazyload.min.js"></script>
    <script>
        window.lazyLoadOptions = {
            elements_selector: ".lazy",
            threshold: 0
        };
    </script>
 

 

 

 

 



 



 


    
 


    
<script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js"></script>

    
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.4.1/dist/jquery.fancybox.min.css">

    
<script src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.4.1/dist/jquery.fancybox.min.js"></script>

    <script>
        let lazyloadT = Boolean('true'),
            auto_fancybox = Boolean('false')
        if (auto_fancybox) {
            $(".post__content").find('img').each(function () {
                var element = document.createElement("a");
                $(element).attr("data-fancybox", "gallery");
                $(element).attr("href", $(this).attr("src"));
                if (lazyloadT) {
                    $(element).attr("href", $(this).attr("data-srcset"));
                }
                $(this).wrap(element);
            });
        } else {
            $(".post__content").find("fancybox").find('img').each(function () {
                var element = document.createElement("a");
                $(element).attr("data-fancybox", "gallery");
                $(element).attr("href", $(this).attr("src"));
                if (lazyloadT) {
                    $(element).attr("href", $(this).attr("data-srcset"));
                }
                $(this).wrap(element);
            });
        }
    </script>
 

 

 

 

 


    

    
    
    
    <script>
        function loadComment() {
            let e;
            (e = document.createElement("script")).src = 'https://cdn.jsdelivr.net/npm/valine@1.4.14/dist/Valine.min.js',
            document.body.appendChild(e);
            e.onload = () => {
                var valineConfig = {"appId":"c21JqSBfScFdueO44Scwp9Ba-gzGzoHsz","appKey":"apETP0QIekHzRXjTHvOnrQmS","placeholder":null,"path":null,"avatar":"retro","meta":["nick","mail","link"],"pageSize":null,"lang":null,"visitor":null,"highlight":null,"avatarForce":null,"recordIP":null,"serverURLs":null,"enableQQ":true,"requiredFields":["nick","mail"],"emojiCDN":null,"emojiMaps":null};
                valineConfig.el = '#valine_container';
                for (var i in valineConfig) {
                    if (valineConfig[i] === null) delete valineConfig[i];
                }
                new Valine(valineConfig);
            };
        }
    
        var runningOnBrowser = typeof window !== "undefined";
        var isBot = runningOnBrowser && !("onscroll" in window) || typeof navigator !== "undefined" && /(gle|ing|ro|msn)bot|crawl|spider|yand|duckgo/i.test(navigator.userAgent);
        var supportsIntersectionObserver = runningOnBrowser && "IntersectionObserver" in window;
    
        setTimeout(function () {
            if (!isBot && supportsIntersectionObserver) {
                var comment_observer = new IntersectionObserver(function(entries) {
                    if (entries[0].isIntersecting) {
                        loadComment();
                        comment_observer.disconnect();
                    }
                }, { threshold: [0] });
                comment_observer.observe(document.getElementById('comment'));
            } else {
                loadComment();
            }
        }, 1);
    </script>


    
    
    
    
    

    
    
    
    
    

    
    
    



    </body>
</html>
